Vitalii Vasylenko
Vitalii Vasylenko

Reputation: 4876

Customizing selected ListboxItem

I have a ListBox (actually, i have a Telerik's RadJumpList, but afaik it is inherited from ListBox) with custom ItemContainerStyle. Each item contains a rectangle (tile) and 2 strings. So far, it works okay by default: when i'm selecting an item, color of strings is changing, and rectangle has const color.

<DataTemplate x:Key="DataTemplate1">
        <Grid Margin="0,0,12,12">
            <Rectangle
                x:Name="SlotTile"
                Width="99" Height="99" Fill="Gray"/>

            <StackPanel Grid.Row="0">
                <TextBlock 
                    FontWeight="Black" 
                    FontSize="{StaticResource PhoneFontSizeSmall}" 
                    Text="{Binding Title, Converter={StaticResource ToUpperConverter}}" />
                <TextBlock 
                    FontFamily="{StaticResource PhoneFontFamilySemiBold}" 
                    FontSize="{StaticResource PhoneFontSizeSmall}" 
                    Text="{Binding Information}" />
            </StackPanel>
        </Grid>
    </DataTemplate>

What i want to do now is to customize selected item: tile's color should be changed, while color of the strings should be the same.

I'm trying to set a custom style, using VisualStateManager, but i have no idea how to get rectangle's and string's color.

<Style x:Name="MySlotStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid 
                        Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ColorAnimation
                                            Storyboard.TargetName=""
                                            Storyboard.TargetProperty=""
                                            />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unelected">
                                    <Storyboard>

                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

So, the question is how to set DataTemplate's properties from the Style.

EDIT: uploaded a sample: http://1drv.ms/1cJrjZ4

EDIT2: i extracted (and modified a bit) a style from checkbox: http://pastebin.com/2JV7d5We They are describing the control inside of the ControlTemplate.

So, i planned to get rid of DataTemplate and move everything to the Style.Template.ControlTemplate. Now, when i'm trying to create a Template binding to a new property (color of the rectangle), it says "the member fill is not recognized".

<Style x:Name="TestStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid Margin="0,0,12,12">
                        <VisualStateManager.VisualStateGroups>
                            ****
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SlotTile" Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Description" Storyboard.TargetProperty="TextForeground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BlackBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                            <Rectangle
                                x:Name="SlotTile"
                                Width="99" Height="99" 
                                Fill="{TemplateBinding Fill}"/>

                            <TextBlock 
                                x:Name="Description"
                                Foreground="{TepmlateBinding TextForeground}"
                                Text="{Binding Title}" />

                            ****
                        </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Upvotes: 0

Views: 1050

Answers (2)

Olivier Payen
Olivier Payen

Reputation: 15268

You should edit a copy of the ItemContainerStyle style and put your grid that acts as your container inside it. Then you can edit the VisualState.Selected storyboard and set the target as your Rectangle and the TargetProperty as Fill.

Here is the XAML code for the ItemContainerStyle:

<Style x:Key="ItemContainerCustomStyle" TargetType="ListBoxItem">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="SlotTile">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid Margin="0,0,12,12">
                        <Rectangle
                            x:Name="SlotTile"
                            Width="99" Height="99" />
                        <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

EDIT: you could even simplify it by using the Border container element from the default style. Thus you can remove the Grid and Rectangle elements.

<Style x:Key="ItemContainerCustomStyle" TargetType="ListBoxItem">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border Width="99" Height="99" x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver"/>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentContainer"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="LayoutRoot">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 1

Anton Sizikov
Anton Sizikov

Reputation: 9240

Can't you set those properties by name?

<ColorAnimation
          Storyboard.TargetName="SlotTile"
          Storyboard.TargetProperty="Fill"
          ...
          />

How to customize the WP7 ListBox Selected Item | Part1

How to customize the WP7 ListBox Selected Item | Part2

Upvotes: 0

Related Questions