かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

GridViewの項目でタップしたときのアニメーションを要素によって無効化したり有効化したるする方法

先日、酢酸先生(id:ch3cooh393)に、タップしたときのアニメーション無効化する方法ないの?って聞かれたので、全部無効化してしまいました。コードレシピにコードをあげてます。

でも、GridViewの中のアイテムを全部無効化したいんじゃなくて一部だけ無効化したりしたいんだよというご要望だったので、それのやりかたを・・・。

結局ItemContainerStyleを指定してやれば、どうにでもなるので、ItemContainerStyleSelectorプロパティにStyleを選択するようなのをつっこんでやればOKです。

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace NoSwipeAnimationGridViewApp
{
    public class GridViewItemContainerStyleSelector : StyleSelector
    {
        /// <summary>
        /// 奇数の値用スタイル
        /// </summary>
        public Style OddStyle { get; set; }

        /// <summary>
        /// 偶数の値用スタイル
        /// </summary>
        public Style EvenStyle { get; set; }

        protected override Style SelectStyleCore(object item, DependencyObject container)
        {
            var i = (int)item;
            return i % 2 == 0 ?
                EvenStyle :
                OddStyle;
        }
    }

}

コードレシピのサンプルに普通のGridViewItemのStyleを定義しておいて、こんな感じでXAMLを書いておくと

<Page
    x:Name="pageRoot"
    x:Class="NoSwipeAnimationGridViewApp.MainPage"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:NoSwipeAnimationGridViewApp"
    xmlns:common="using:NoSwipeAnimationGridViewApp.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:System="using:System"
    mc:Ignorable="d">

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">GridView no swipe animation application</x:String>
        <Style x:Key="NoSwipeAnimationGridViewItemStyle" TargetType="GridViewItem">
            <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
            <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="TabNavigation" Value="Local"/>
            <Setter Property="IsHoldingEnabled" Value="True"/>
            <Setter Property="Margin" Value="0,0,2,2"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="GridViewItem">
                        <Border Padding="{TemplateBinding Padding}">
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="GridViewItemStyle" TargetType="GridViewItem">
            <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
            <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="TabNavigation" Value="Local"/>
            <Setter Property="IsHoldingEnabled" Value="True"/>
            <Setter Property="Margin" Value="0,0,2,2"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="GridViewItem">
                        <GridViewItemPresenter 
                            CheckHintBrush="{ThemeResource ListViewItemCheckHintThemeBrush}" 
                            CheckBrush="{ThemeResource ListViewItemCheckThemeBrush}" 
                            ContentMargin="4" 
                            ContentTransitions="{TemplateBinding ContentTransitions}" 
                            CheckSelectingBrush="{ThemeResource ListViewItemCheckSelectingThemeBrush}" 
                            DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" 
                            DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" 
                            DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" 
                            DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" 
                            FocusBorderBrush="{ThemeResource ListViewItemFocusBorderThemeBrush}" 
                            HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            Padding="{TemplateBinding Padding}" 
                            PointerOverBackgroundMargin="1" 
                            PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" 
                            PointerOverBackground="{ThemeResource ListViewItemPointerOverBackgroundThemeBrush}" 
                            ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" 
                            SelectedPointerOverBorderBrush="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}"
                            SelectionCheckMarkVisualEnabled="True" 
                            SelectedForeground="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" 
                            SelectedPointerOverBackground="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" 
                            SelectedBorderThickness="{ThemeResource GridViewItemCompactSelectedBorderThemeThickness}" 
                            SelectedBackground="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}" 
                            VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        
        <local:GridViewItemContainerStyleSelector 
            x:Key="itemContainerStyleSelector" 
            OddStyle="{StaticResource GridViewItemStyle}"
            EvenStyle="{StaticResource NoSwipeAnimationGridViewItemStyle}"/>
    </Page.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="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Margin="39,59,39,0" Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
                        Style="{StaticResource NavigationBackButtonNormalStyle}"
                        VerticalAlignment="Top"
                        AutomationProperties.Name="Back"
                        AutomationProperties.AutomationId="BackButton"
                        AutomationProperties.ItemType="Navigation Button"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1" 
                        IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" Margin="0,0,30,40"/>

        </Grid>
        <GridView 
            Name="gridViewItem" 
            Grid.Row="1" 
            Padding="120,0,0,10"
            ItemsSource="{Binding GridViewItems}" 
            SelectionMode="Single"
            IsSwipeEnabled="False" 
            ItemContainerStyleSelector="{StaticResource itemContainerStyleSelector}">
            <GridView.ItemTemplate>
                <!-- Dummy item template -->
                <DataTemplate>
                    <Border 
                        Width="250" 
                        Height="250" 
                        BorderBrush="{ThemeResource ListBoxBorderThemeBrush}"
                        BorderThickness="1"
                        Background="{ThemeResource ListBoxBackgroundThemeBrush}" />
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>
    </Grid>
</Page>

これで、データが偶数のものは選択しても反応しなくて、奇数のものはぷにっとアニメーションします。