適切なマージンを持った GridView のスタイル定義 (3)
※Release Preview での状況は以下の記事を参照してください。
Release Preview における GridView の問題点 (1) - rebuild
2回にわたって GridView のスタイル定義について書きましたが、最後に ListView も含めて必要な作業をまとめておきます。
必要になる作業は以下の通りです。
- 適切なマージンを持った GridView / ListView のスタイルを定義する(予め定義しておけば使いまわせる)。
- GridView / ListView を囲んでいる ScrollViewer 削除して GridView / ListView を外に出す。この時、ScrollViewer に設定されていた Grid.Row, Margin, Visibility のプロパティは その中にあった GridView / ListView に設定する。
- GridView / ListView の Style に定義したスタイルを設定する。GridView に設定するのはランドスケープ用の物。
- ポートレート時の VisualState に定義されている、GridView の Margin を変える KeyFrame を削除する。代わりに GridView の Style をポートレート用の物に変える KeyFrame を追加する。
- スナップ時の VisualState に定義されている ScrollViewer の Visibility を変える KeyFrame を、GridView / ListView を対象とするように変更する。
以下に定義したスタイルと、グリッドアプリケーションの先頭ページをスタイルを使うように変更した物を載せます。
スタイル定義(CustomGridViewStyle.xaml)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:StyleDefineTest"> <Style x:Key="LandscapeGridViewStyle" TargetType="GridView"> <Setter Property="Padding" Value="0,0,0,10"/> <Setter Property="IsTabStop" Value="False"/> <Setter Property="TabNavigation" Value="Once"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled"/> <Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled"/> <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/> <Setter Property="IsSwipeEnabled" Value="True"/> <Setter Property="ItemContainerTransitions"> <Setter.Value> <TransitionCollection> <AddDeleteThemeTransition/> <ContentThemeTransition/> <ReorderThemeTransition/> <EntranceThemeTransition IsStaggeringEnabled="False"/> </TransitionCollection> </Setter.Value> </Setter> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <WrapGrid Orientation="Vertical"/> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="GridView"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer x:Name="ScrollViewer" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ItemsPresenter Margin="116,0,40,46"/> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="PortraitGridViewStyle" TargetType="GridView"> <Setter Property="Padding" Value="0,0,0,10"/> <Setter Property="IsTabStop" Value="False"/> <Setter Property="TabNavigation" Value="Once"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled"/> <Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled"/> <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/> <Setter Property="IsSwipeEnabled" Value="True"/> <Setter Property="ItemContainerTransitions"> <Setter.Value> <TransitionCollection> <AddDeleteThemeTransition/> <ContentThemeTransition/> <ReorderThemeTransition/> <EntranceThemeTransition IsStaggeringEnabled="False"/> </TransitionCollection> </Setter.Value> </Setter> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <WrapGrid Orientation="Vertical"/> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="GridView"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer x:Name="ScrollViewer" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ItemsPresenter Margin="96,0,10,56"/> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="SnappedListViewStyle" TargetType="ListView"> <Setter Property="IsTabStop" Value="False"/> <Setter Property="TabNavigation" Value="Once"/> <Setter Property="IsSwipeEnabled" Value="True"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/> <Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled"/> <Setter Property="ScrollViewer.ZoomMode" Value="Disabled"/> <Setter Property="ItemContainerTransitions"> <Setter.Value> <TransitionCollection> <AddDeleteThemeTransition/> <ContentThemeTransition/> <ReorderThemeTransition/> <EntranceThemeTransition IsStaggeringEnabled="False"/> </TransitionCollection> </Setter.Value> </Setter> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListView"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer x:Name="ScrollViewer" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ItemsPresenter Margin="10,-10,0,60"/> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
グループアイテム表示ページ(GroupedItemsPage.xaml)
<common:LayoutAwarePage x:Name="pageRoot" x:Class="StyleDefineTest.GroupedItemsPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:StyleDefineTest" xmlns:data="using:StyleDefineTest.Data" xmlns:common="using:StyleDefineTest.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <UserControl.Resources> <!-- Collection of grouped items displayed by this page --> <CollectionViewSource x:Name="groupedItemsViewSource" Source="{Binding Groups}" IsSourceGrouped="true" ItemsPath="Items" d:Source="{Binding ItemGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/> </UserControl.Resources> <!-- This grid acts as a root panel for the page that defines two rows: * Row 0 contains the back button and page title * Row 1 contains the rest of the page layout --> <Grid Background="{StaticResource ApplicationPageBackgroundBrush}"> <Grid.RowDefinitions> <RowDefinition Height="140"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!-- Back button and page title --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/> <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Grid.Column="1" Style="{StaticResource PageHeaderTextStyle}"/> </Grid> <!-- Horizontal scrolling grid used in most view states --> <GridView x:Name="itemGridView" AutomationProperties.AutomationId="ItemGridView" AutomationProperties.Name="Grouped Items" Margin="0,-3,0,0" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}" ItemTemplate="{StaticResource Standard250x250ItemTemplate}" SelectionMode="None" IsItemClickEnabled="True" ItemClick="ItemView_ItemClick" Grid.Row="1" Style="{StaticResource LandscapeGridViewStyle}" d:LayoutOverrides="Width, Height"> <GridView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <Grid Margin="1,0,0,6"> <Button AutomationProperties.Name="Group Title" Content="{Binding Title}" Click="Header_Click" Style="{StaticResource TextButtonStyle}"/> </Grid> </DataTemplate> </GroupStyle.HeaderTemplate> <GroupStyle.Panel> <ItemsPanelTemplate> <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </GridView.GroupStyle> </GridView> <!-- Vertical scrolling list only used when snapped --> <ListView x:Name="itemListView" AutomationProperties.AutomationId="ItemListView" AutomationProperties.Name="Grouped Items" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}" ItemTemplate="{StaticResource Standard80ItemTemplate}" SelectionMode="None" IsItemClickEnabled="True" Grid.Row="1" Visibility="Collapsed" ItemClick="ItemView_ItemClick" Style="{StaticResource SnappedListViewStyle}" d:LayoutOverrides="Width, Height"> <ListView.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <Grid Margin="7,7,0,0"> <Button AutomationProperties.Name="Group Title" Content="{Binding Title}" Click="Header_Click" Style="{StaticResource TextButtonStyle}"/> </Grid> </DataTemplate> </GroupStyle.HeaderTemplate> </GroupStyle> </ListView.GroupStyle> </ListView> <VisualStateManager.VisualStateGroups> <!-- Visual states reflect the application's view state --> <VisualStateGroup> <VisualState x:Name="FullScreenLandscape"/> <VisualState x:Name="Filled"/> <!-- The entire page respects the narrower 100-pixel margin convention for portrait --> <VisualState x:Name="FullScreenPortrait"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitGridViewStyle}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <!-- The back button and title have different styles when snapped, and the list representation is substituted for the grid displayed in all other view states --> <VisualState x:Name="Snapped"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Grid> </common:LayoutAwarePage>
これで、現在認識している問題は解決していると思います。
この問題は Consumer Preview で確認していますが、かなり大きな問題だと思いますので、今後のアップデートで何らかの対策が行われるのではないかと思います。
現状での対策方法もかなり面倒(スタイル定義以外は関係する画面全てで変更が必要)な物なので、すぐに対応が必要でなければ、今後のアップデートで対策が行われるか様子を見てから動いた方が良いでしょう。