Создание адаптивного gridview с возможностью прокрутки

#c# #xaml #uwp #uwp-xaml

#c# #xaml #uwp #uwp-xaml

Вопрос:

Для университетского проекта я работаю над UWP-приложением, которое отображает текущую информацию о погоде и имеет интерфейс, подобный Cortana, для управления определенными частями умного дома.

Интерфейс состоит из трех столбцов с одной строкой для представления на рабочем столе, и эти три столбца выровнены как три строки в одном столбце на мобильных устройствах. Эту часть я понял, следуя руководству и изменив код в соответствии со своими конкретными потребностями.

Теперь у меня проблема в том, что столбцы, когда они помещаются в виде строки, уменьшаются до размера 1/3 экрана. Я установил жестко заданный размер 500, чтобы посмотреть, смогу ли я работать с фиксированными значениями, поскольку внутренние элементы не сильно меняют размер. Однако, когда я делаю это, представление не прокручивается, и большая часть второй строки и вся третья строка не видны пользователю. Я пытался решить эту проблему, добавив приведенный ниже код в основную сетку, но безрезультатно.

 <Grid x:Name="MainGrid" ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.VerticalScrollBarVisibility="Visible">
  

TL; DR: Как мне создать адаптивный макет сетки, чтобы его можно было прокручивать, когда сетка становится слишком большой.

Код XAML:

 <Page
x:Class="UWPWeather.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPWeather"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">

<Grid x:Name="MainGrid" ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.VerticalScrollBarVisibility="Visible">

    <Grid.Background>
        <ImageBrush Stretch="Fill" ImageSource="Assets/blue-sea-horizon.jpg"/>
    </Grid.Background>

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="WideState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="1100" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MainGrid.RowDefinitions[1].Height" Value="0*"/>
                    <Setter Target="MainGrid.RowDefinitions[2].Height" Value="0*"/>
                    <Setter Target="MainGrid.ColumnDefinitions[1].Width" Value="1*"/>
                    <Setter Target="MainGrid.ColumnDefinitions[2].Width" Value="1*"/>
                    <Setter Target="FirstGrid.Margin" Value="0 0 0 0"/>
                    <Setter Target="SecondGrid.Margin" Value="0 0 0 0"/>
                    <Setter Target="SecondGrid.(Grid.Column)" Value="1"/>
                    <Setter Target="SecondGrid.(Grid.Row)" Value="0"/>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="FirstGrid.Margin" Value="0 0 0 6"/>
                    <Setter Target="SecondGrid.Margin" Value="0 6 0 0"/>
                    <Setter Target="MainGrid.RowDefinitions[0].Height" Value="500"/>
                    <Setter Target="MainGrid.RowDefinitions[1].Height" Value="500"/>
                    <Setter Target="MainGrid.RowDefinitions[2].Height" Value="500"/>
                    <Setter Target="MainGrid.ColumnDefinitions[1].Width" Value="0*"/>
                    <Setter Target="MainGrid.ColumnDefinitions[2].Width" Value="0*"/>
                    <Setter Target="SecondGrid.(Grid.Column)" Value="0"/>
                    <Setter Target="SecondGrid.(Grid.Row)" Value="1"/>
                    <Setter Target="ThirdGrid.(Grid.Column)" Value="0"/>
                    <Setter Target="ThirdGrid.(Grid.Row)" Value="1"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>


    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>


        <Grid x:Name="FirstGrid" Grid.Column="0" Grid.Row="0" Background="Transparent">
            <Button x:Name="StartRecognition" HorizontalAlignment="Center" VerticalAlignment="Center" Height="200" Width="200" Click="StartVoiceRecog">
                <Button.Background>
                    <ImageBrush Stretch="Uniform" ImageSource="Assets/microphone.png"/>
                </Button.Background>
            </Button>
        </Grid>

        <Grid x:Name="SecondGrid" Grid.Column="1" Grid.Row="0" Background="Transparent">
            <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Padding="0,50,0,0">
                <TextBlock x:Name="LocationTextBlock" FontSize="36" Foreground="White" HorizontalAlignment="Center" TextWrapping="Wrap" />

                <StackPanel Orientation="Horizontal" Padding="5">
                    <Image x:Name="ResultImage" Width="200" Height="200" HorizontalAlignment="Left"/>
                    <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="TempTextBlock" FontSize="60" Foreground="White"/>
                </StackPanel>

                <TextBlock x:Name="DescriptionTextBlock" Padding="5" FontSize="36" Foreground="White" HorizontalAlignment="Center" />
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Padding="5">
                    <Image x:Name="WindDirection" Width="20" Height="20" />
                    <TextBlock x:Name="WindSpeed" FontSize="12" Foreground="White"/>
                </StackPanel>

                <TextBlock x:Name="Pressure" Padding="5" FontSize="12" Foreground="White" HorizontalAlignment="Center" />
                <TextBlock x:Name="Humidity" Padding="5" FontSize="12" Foreground="White" HorizontalAlignment="Center" />

                <StackPanel Orientation="Horizontal" Padding="5" HorizontalAlignment="Center">
                    <Image x:Name="SunRiseImage" Width="20" Height="20"/>
                    <TextBlock x:Name="Sunrise" FontSize="12" Foreground="White"  />
                </StackPanel>

                <StackPanel Orientation="Horizontal" Padding="5" HorizontalAlignment="Center" >
                    <Image x:Name="SunsetImage" Width="20" Height="20"/>
                    <TextBlock x:Name="Sunset" FontSize="12" Foreground="White" />
                </StackPanel>

                <Button x:Name="UpdateWeather" Padding="5" HorizontalAlignment="Center" VerticalAlignment="Center" Height="49" Width="39" Click="UpdateWeatherOnClick">
                    <Button.Background>
                        <ImageBrush Stretch="Fill" ImageSource="Assets/012_restart-512.png"/>
                    </Button.Background>
                </Button>
            </StackPanel>
        </Grid>

    <Grid x:Name="ThirdGrid" Grid.Column="2" Grid.Row="0" Background="Transparent">

    </Grid>
</Grid>
  

Концепция интерфейса:

Широкий интерфейс

Интерфейс узкий

Ответ №1:

Элементы пользовательского интерфейса не станут прокручиваемыми только потому, что вы установили ScrollViewer.VerticalScrollMode="Enabled" для них свойство attached. Эти прикрепленные свойства полезны только для элементов, которые содержат ScrollViewer в своем шаблоне (именно ScrollViewer будет принимать значения прикрепленных свойств).

Если вы хотите, чтобы ваш MainGrid экран можно было прокручивать, вам нужно обернуть его в ScrollViewer. Вам также нужно VisualStateManager.VisualStateGroups будет перенести прикрепленное свойство из MainGrid в ScrollViewer. VisualStateManager.VisualStateGroups должен быть прикреплен к корню шаблона, иначе это не будет иметь никакого эффекта.

 <Page>
    <ScrollViewer>
        <VisualStateManager.VisualStateGroups>
            ...
        </VisualStateManager.VisualStateGroups>
        <Grid x:Name="MainGrid">
            ...
        </Grid>
    </ScrollViewer>
</Page>
  

Комментарии:

1. Я пробовал это, если я оберну сетку в scrollviewer, она потеряет отзывчивость, созданную с помощью VisuelStateManager. есть ли способ обернуть ее в scrollviewer и сохранить отзывчивость?

2. Когда вы оборачиваете свой MainGrid в ScrollViewer, обязательно поднимите VisualStateManager.VisualStateGroups его изнутри MainGrid вверх в ScrollViewer. VisualStateGroups должны быть установлены в корневом элементе шаблона, иначе это не будет иметь никакого эффекта.

3. Да, это была моя ошибка, я еще этого не пробовал. У меня сложилось впечатление, что VisualStateManager.VisualStateGroups был частью элемента grid.