普通はクロススライド(タイルをスクロール方向に交差する下にドラッグさせる)で項目を選択するため原則水平スクロールにするんですが、どうしても!GridView を縦スクロールしたい・・・という場合どうしたらよいか
その場合はウィンドウ幅に応じて列数をレスポンシブに変化させる必要があります
そんな GridView の表示の仕方を作ってみました
まずは XAML の記述
<!-- 水平スクロール グリッド --> <GridView x:Name="itemGridView" Grid.Row="1" Grid.RowSpan="1" AutomationProperties.AutomationId="ItemsGridView" AutomationProperties.Name="Items" IsItemClickEnabled="True" IsSwipeEnabled="false" ItemClick="Presenter.OnItemClick" ItemsSource="{Binding Source={StaticResource itemsViewSource}}" Padding="0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollMode="Auto" SelectionMode="None" TabIndex="1"> <GridView.ItemsPanel> <ItemsPanelTemplate> <VariableSizedWrapGrid Margin="116,0,76,76" ItemHeight="250" ItemWidth="285" Orientation="Horizontal" SizeChanged="Presenter.OnVariableSizedWrapGridSizeChanged" /> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.ItemContainerStyle> <Style TargetType="GridViewItem"> <Setter Property="Margin" Value="0,0,20,20" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="VerticalContentAlignment" Value="Stretch" /> </Style> </GridView.ItemContainerStyle> <GridView.ItemTemplate> <DataTemplate> <Grid> <Image HorizontalAlignment="Center" VerticalAlignment="Top" AutomationProperties.Name="{Binding Content.Title}" Source="{Binding Content.ImageUri}" Stretch="UniformToFill" /> <Border VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}" Padding="15"> <TextBlock FontSize="18" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap"> <Run Text="Photo: " /><Run Text="{Binding Content.Title}" /><Run Text=" by " /><Run Text="{Binding Content.Owner}" /> </TextBlock> </Border> </Grid> </DataTemplate> </GridView.ItemTemplate> </GridView>
GridView.ItemsPanel に VariableSizedWrapGrid を指定して Orientation に Horizontal を指定しているのと、SizeChanged イベントハンドラを追加しました それ以外はいたって普通の GridView の記述です
次に SizeChanged イベントハンドラの中身を記述します
/// <summary> /// GridView 内部の VariableSizedWrapGrid のサイズ変更イベントハンドラ /// </summary> /// <param name="sender">イベント発行者</param> /// <param name="e">イベント引数</param> public void OnVariableSizedWrapGridSizeChanged(object sender, SizeChangedEventArgs e) { var wrapGrid = sender as VariableSizedWrapGrid; if (wrapGrid == null) { return; } switch (wrapGrid.Orientation) { // Z字型の並び順の場合 case Orientation.Horizontal: wrapGrid.MaximumRowsOrColumns = (int)Math.Floor(e.NewSize.Width / wrapGrid.ItemWidth); break; // И字型の並び順の場合 case Orientation.Vertical: wrapGrid.MaximumRowsOrColumns = (int)Math.Floor(e.NewSize.Height / wrapGrid.ItemHeight); break; } }
VariableSizedWrapGrid をキャストで参照後、Orientation の設定に応じて VariableSizedWrapGrid.MaximumRowsOrColumns の値を切り替えています
VariableSizedWrapGrid.MaximumRowsOrColumns は表示される最大列数もしくは最大行数で Orientation の設定応じて最大列数か最大行数として扱われるかが変わります
新しい MaximumRowsOrColumns の値は ItemWidth や ItemHeight で新たな VariableSizedWrapGrid の Width や Height を割った切り捨て値を指定しているだけです
これだけでできました!簡単ですね