かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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>

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