mister_giga
mister_giga

Reputation: 612

UWP ListView modifycontrols in datatemplate when item is selected

I have ListView and it's DataTemplate ItemTemplate looks like this>

<DataTemplate>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Rectangle Fill="Black"/>
        <TextBlock Text="{Binding Title}"/>
    </Grid>
</DataTemplate>

When the item in the ListView is selected I want the Rectangle to have Fill with value of Whilte.

For WPF I cound use Triggers but on UWP there are no any as I found.

I dont want to use C# to listen for ItemSelected event of ListView and then change all items color to Black and then set SelectedItem's color to white, because I will have too many items in the ListView

Upvotes: 0

Views: 1273

Answers (2)

RicardoPons
RicardoPons

Reputation: 1353

There is a very simple way to solve this problem with UWP Apps. As you know UWP Apps does not support Triggers like WPF apps. Always when I have this scenario I prefer to use Behaviors.

You can listen with a custom Behavior when the item is selected and change the value of the color of some property in your model.

Example:

<Rectangle Fill="{Binding MyColor,Mode=TwoWay}"/>

In the event handler of your behavior just change the color of your property(MyColor).

Upvotes: 0

Vincent
Vincent

Reputation: 3746

The easiest way to do that is to customize the ListView.ItemContainerStyle. You will find a lot of usefull details here.

The idea is to create a custom layout for the list items. The layout will contain your black rectangle on the left and your template (the textbox) on the right.

So basically, the listview declaration becomes (some code has been removed for clarity):

<ListView x:Name="list" SelectionMode="Single">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Data">
                <TextBlock Text="{x:Bind Title}" />
            </DataTemplate>
        </ListView.ItemTemplate>

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalAlignment" Value="Stretch" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                             <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="8" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>

                                <Rectangle x:Name="sideRect" Fill="Black" />

                                <Grid
                                    x:Name="ContentPresenterGrid"
                                    Margin="0,0,0,0"
                                    Background="Transparent"
                                    Grid.Column="1">
                                    <Grid.RenderTransform>
                                        <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                                    </Grid.RenderTransform>
                                    <ContentPresenter
                                        x:Name="ContentPresenter"
                                        Margin="{TemplateBinding Padding}"
                                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                        Content="{TemplateBinding Content}"
                                        ContentTemplate="{TemplateBinding ContentTemplate}"
                                        ContentTransitions="{TemplateBinding ContentTransitions}" />
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

You will then have to update the visual states to set your rectangle color to what you want for each state as for example: (I've removed some animations for clarity)

<VisualState x:Name="Selected">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

The full code:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView x:Name="list" SelectionMode="Single">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Data">
                <TextBlock Text="{x:Bind Title}" />
            </DataTemplate>
        </ListView.ItemTemplate>

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalAlignment" Value="Stretch" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <Grid
                                x:Name="ContentBorder"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">

                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal">
                                            <Storyboard>
                                                <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="PointerOver">
                                            <Storyboard>

                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Pressed">
                                            <Storyboard>

                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                </ObjectAnimationUsingKeyFrames>
                                                <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Selected">
                                            <Storyboard>
                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                </ObjectAnimationUsingKeyFrames>

                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Red" />
                                                </ObjectAnimationUsingKeyFrames>

                                                <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="PointerOverSelected">
                                            <Storyboard>


                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                </ObjectAnimationUsingKeyFrames>

                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Green" />
                                                </ObjectAnimationUsingKeyFrames>

                                                <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="PressedSelected">
                                            <Storyboard>



                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                                </ObjectAnimationUsingKeyFrames>

                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="sideRect" Storyboard.TargetProperty="Fill">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="Yellow" />
                                                </ObjectAnimationUsingKeyFrames>


                                                <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="DisabledStates">
                                        <VisualState x:Name="Enabled" />
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <DoubleAnimation
                                                    Storyboard.TargetName="ContentBorder"
                                                    Storyboard.TargetProperty="Opacity"
                                                    To="{ThemeResource ListViewItemDisabledThemeOpacity}"
                                                    Duration="0" />
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="MultiSelectStates">
                                        <VisualState x:Name="MultiSelectDisabled">
                                            <Storyboard>


                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                                    <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
                                                    <SplineDoubleKeyFrame
                                                        KeySpline="0.1,0.9,0.2,1"
                                                        KeyTime="0:0:0.333"
                                                        Value="0" />
                                                </DoubleAnimationUsingKeyFrames>

                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MultiSelectEnabled">
                                            <Storyboard>


                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                                    <EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
                                                    <SplineDoubleKeyFrame
                                                        KeySpline="0.1,0.9,0.2,1"
                                                        KeyTime="0:0:0.333"
                                                        Value="0" />
                                                </DoubleAnimationUsingKeyFrames>


                                                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterGrid" Storyboard.TargetProperty="Margin">
                                                    <DiscreteObjectKeyFrame KeyTime="0" Value="32,0,0,0" />
                                                </ObjectAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>

                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="8" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>

                                <Rectangle x:Name="sideRect" Fill="Black" />


                                <Grid
                                    x:Name="ContentPresenterGrid"
                                    Margin="0,0,0,0"
                                    Background="Transparent"
                                    Grid.Column="1">
                                    <Grid.RenderTransform>
                                        <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                                    </Grid.RenderTransform>
                                    <ContentPresenter
                                        x:Name="ContentPresenter"
                                        Margin="{TemplateBinding Padding}"
                                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                        Content="{TemplateBinding Content}"
                                        ContentTemplate="{TemplateBinding ContentTemplate}"
                                        ContentTransitions="{TemplateBinding ContentTransitions}" />
                                </Grid>
                            </Grid>
                        </ControlTemplate>

                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
</Grid>

Upvotes: 3

Related Questions