0
votes

I am building a UWP app utilizing an image and a textblock. I want to follow the design guidelines and have two columns for larger devices and one column for phones. I am not using either Grid now GridView because those two layouts did not work particularly well with my VisualStates (either the textblock did not show, or it was limited in height to the same height as the image, and so on).

Here is what my XAML looks like:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden">
    <StackPanel Orientation="Horizontal"  Background="Black" Margin="24" Name="IssuePanel">
        <Image Name="CoverImage" Width="300" VerticalAlignment="Top" />
        <TextBlock Name="Description" HorizontalAlignment="Left" Foreground="White" TextWrapping="WrapWholeWords" Text="{Binding Description}" />
    </StackPanel>

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="320"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="IssuePanel.Margin" Value="12"/>
                    <Setter Target="IssuePanel.Orientation" Value="Vertical"/>
                    <Setter Target="CoverImage.Width" Value="200"/>
                    <Setter Target="Description.Width" Value="320"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="720"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="Description.Width" Value="320"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="1024"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="Description.Width" Value="720"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</ScrollViewer>

As you can see, I am setting the Description textblock's width in all the Visual states. While it breaks correctly, it looks like shit. I want the text to always go to the end of the window/page. What is the better way to do this sort of scenario?

2

2 Answers

2
votes

The answer to your text layout and wrapping problems is RelativePanels. Having the StackPanel in your view hierarchy is not allowing the TextBlock to wrap when it should.

A RelativePanel lets you place items inside of it in relation to one another. This is used extensively to provide responsive UI for different form factors (exactly what you are trying to do). I modified your code below to make the layout work.

<Grid>
    <ScrollViewer VerticalScrollMode="Auto" HorizontalScrollMode="Disabled" VerticalScrollBarVisibility="Auto">
        <RelativePanel Background="Black" Margin="24" Name="IssuePanel">
            <Image RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignTopWithPanel="True" 
                   Name="CoverImage" Width="300" Height="200" />
            <TextBlock RelativePanel.AlignTopWithPanel="True" RelativePanel.RightOf="CoverImage" 
                       Name="Description" HorizontalAlignment="Left" Foreground="White" TextWrapping="WrapWholeWords">
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
                       Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.Description with some really long text... blah blah blah.
            </TextBlock>
        </RelativePanel>
    </ScrollViewer>

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="320"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="IssuePanel.Margin" Value="12"/>
                    <Setter Target="CoverImage.Width" Value="200"/>
                    <Setter Target="Description.(RelativePanel.AlignTopWithPanel)" Value="false"/>
                    <Setter Target="Description.(RelativePanel.Below)" Value="CoverImage"/>
                    <Setter Target="Description.(RelativePanel.AlignLeftWithPanel)" Value="true"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="720"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="1024"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

The visual state setter for the smallest width moves the relation to have the description realign below the image and to the left of the panel. In the wider states, you don't need to do anything. Once you remove the StackPanel, the text wraps as you'd expect.

0
votes

You can use wrapPanel control which is present in "using:Microsoft.Toolkit.Uwp.UI.Controls" library.It will easily wrap the content according to window size. Relative Panel makes it complex when you are designing a responsive app.