かずき( id:okazuki )さんに「WindowsストアアプリのGridViewでタイルをタップした時に押した時のチルトエフェクトアニメが動いちゃうんですけど、アイテムごとにアニメするかしないか決めたいんですよ」と、何かのプロパティを変更するいいんでしょ?的なノリで話をしました。
iOSのUITableViewでセルを返す時には、セルの選択状態を青色や灰色のする場合にUITableViewCellクラスのselectionStyleプロパティ
の値を変更します。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } return cell; }
今回やりたかったことは、セル単位で選択しない状態にする cell.selectionStyle = UITableViewCellSelectionStyleNone;
をWindowsストアアプリでやりたかったのです。これをかずき( id:okazuki )さんがこのように書いてくださいました。
上記の記事を参考にして、僕の方でも実装してみました。
かずきさんの記事では、タップしたときにアニメーションさせる普通のスタイルGridViewItemStyle
とアニメーションさせないスタイルNoSwipeAnimationGridViewItemStyle
のスタイルを定義して、セレクターItemContainerStyleSelector
によってどちらのスタイルを使用するか決めています。重要なのは下記の要素です。
- GridViewアイテムを押したした時にアニメーションさせる普通のスタイル
- GridViewItemStyle
- GridViewアイテムを押したした時にアニメーションさせないスタイル
- NoSwipeAnimationGridViewItemStyle
- どちらのスタイルを使用するかを決定するセレクター
- ItemContainerStyleSelector
ItemContainerStyleSelectorを実装する
プロジェクトにGridViewItemContainerStyleSelector.cs
を新規追加して、以下のようにセレクターを書きます(かずきさんのソースコードをコピペしただけです)。
どんなアイテムが来ても大丈夫なようにクラス変数にcount
を持たせて、奇数であればOddStyleプロパティ
に登録されたスタイルが適用され、countの値が偶数であればEvenStyleプロパティ
に登録されたスタイルが適用されます。
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace NoPushSample { public class GridViewItemContainerStyleSelector : StyleSelector { /// <summary> /// 奇数の値用スタイル /// </summary> public Style OddStyle { get; set; } /// <summary> /// 偶数の値用スタイル /// </summary> public Style EvenStyle { get; set; } static int count; protected override Style SelectStyleCore(object item, DependencyObject container) { count++; return (count % 2 == 0) ? EvenStyle : OddStyle; } } }
XAML側のGroupedItemsPageを実装する
XAML側でGridViewItemStyle
とNoSwipeAnimationGridViewItemStyle
のスタイルを定義します。
GirdViewを選択して、右クリックしてコンテキストメニューから「追加テンプレートの編集」、「生成されたアイテムコンテナーの編集(ItemContainerStyle)」、「コピーして編集」の順に選択します。
新しく作成するItemContainerStyleの名前を何にするかを決めます。ここではGridViewItemStyle
という名前を付けました。このスタイルはチルトエフェクトさせないスタイルです。
NoSwipeAnimationGridViewItemStyle
は、かずきさんのブログからコピペしました。
<!-- GridViewアイテムを押したした時にアニメーションさせないスタイル --> <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="Padding" Value="4"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="GridViewItem"> <Border Padding="{TemplateBinding Padding}"> <ContentPresenter /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- GridViewアイテムを押したした時にアニメーションさせる普通のスタイル --> <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}"/>
上記で定義したスタイルとスタイルセレクターを、下記のようにGridViewへ適用します。
<!-- 水平スクロール グリッド --> <GridView x:Name="itemGridView" AutomationProperties.AutomationId="ItemGridView" AutomationProperties.Name="Grouped Items" Grid.RowSpan="2" Padding="116,137,40,46" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}" SelectionMode="None" IsSwipeEnabled="false" IsItemClickEnabled="True" ItemClick="ItemView_ItemClick" ItemTemplate="{StaticResource GridViewItemTemplate}" ItemContainerStyleSelector="{StaticResource itemContainerStyleSelector}" > <GridView.ItemsPanel> <ItemsPanelTemplate> <ItemsWrapGrid GroupPadding="0,0,70,0"/> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.GroupStyle> <GroupStyle HeaderTemplate="{StaticResource GridViewHeaderTemplate}" /> </GridView.GroupStyle> </GridView>
以上で、できあがったのが下図のようなアプリです。見た目はテンプレートそのままのアプリですが「選択できるアイテム」「選択できないアイテム」が順々に表示されます。
関係ない要素が多かったので、ここでは重要な部分をXAMLから切り張りしています。手を入れたXAMLをみたいという方は、こちらをご覧ください。