metaphori
metaphori

Reputation: 2811

GridView's ItemContainerStyle and selection states

I'm trying to change the appearance of gridview items when they are selected. (Before, I used a trick with an IsSelected property in the ViewModel object bound to the containing grid and a bool-to-color converter, but I recognize that it is bad)

To do so, I do:

    <GridView ItemContainerStyle="{StaticResource GridViewItemContainerStyle}" ...> ...

and

    <Style x:Key="GridViewItemContainerStyle" TargetType="GridViewItem">
        <Setter Property="Background" Value="Red" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="GridViewItem">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Background)" Storyboard.TargetName="itemGrid">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Black"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="UnselectedSwiping"/>
                                <VisualState x:Name="UnselectedPointerOver"/>
                                <VisualState x:Name="Selecting"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Background)" Storyboard.TargetName="itemGrid">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="White"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="SelectedSwiping"/>
                                <VisualState x:Name="Unselecting"/>
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="SelectedUnfocused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid ... x:Name="itemGrid">
                              <!-- HERE MY DATA TEMPLATE -->
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

When I run the app, the items are Black (as in the "normal" state). But selecting them does not turn them into White. Where am I wrong?

Moreover, it there a way to set "ItemContainerStyle" without having it to "overwrite" the "ItemTemplate" ???

Upvotes: 1

Views: 4646

Answers (1)

botja
botja

Reputation: 116

You DataTemplate should be inside the ItemTemplate property of the GridView element in your page's XAML. Make a separate XAML file (ResourceDictionary), for example CustomStyles.xaml. Reference it in App.xaml like this:

    <Application.Resources>
    <!-- Application-specific resources -->
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="PathToCustomStyles.xaml" />             
        </ResourceDictionary.MergedDictionaries>          
    </ResourceDictionary>
</Application.Resources>

You can find on MSDN the default template for GridViewItem (http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj709915.aspx), under the Default style section (second, longer XAML).

Copy that and paste it into CustomStyles.xaml. Just give it some key like:

<Style TargetType="GridViewItem" x:Key="CustomGridViewItemStyleWithWhiteSelectionBackground">...

As you can see, Selected visual state changes the opacity of three targets, SelectionBackground, SelectedBorder and SelectedCheckMark. So, these elements are not visible in Normal state because their opacity is zero. Find those three elements down below, and change their properties if needed. For the background change the Fill property of the SelectionBackground rectangle:

<Rectangle x:Name="SelectionBackground"
    Margin="4"
    Fill="White"
    Opacity="0" />

Now, when the selection occurs, this element's opacity will be changed to 1 and since you set it's Fill to be white, the background of the selected item will be white. And don't forget to reference this style in the definition of the GridView:

<GridView ItemContainerStyle="{StaticResource CustomGridViewItemStyleWithWhiteSelectionBackground}" ...>
    <GridView.ItemTemplate>
    <DataTemplate>
    ...define your template here...
    </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

Edit:

This is the expanded style XAML, probably more suitable for some more complicated style changes. If you want to change only the background, you should take the first style from that MSDN link above under the Default style section, and just edit this (and give it some style key, so you don't overwrite the default one):

SelectedBackground="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}"

Upvotes: 4

Related Questions