Reputation: 298
I am creating a custom controltemplate for ListBox and I'm having difficulties with the visual states. When using the VisualState MouseOver, it affects all the items including the selected item, which I want to have separate styling.
In Metro, there is SelectedPointerOver, is there anything equivalent in WPF or other alternatives?
Edit:
For example, all items initially have black foreground.
When one item is selected, its foreground turns white (and non-selected items remain black foreground).
And now when I MouseOver the non-selected item, I will like its foreground to turn blue, and when I MouseOver the selected item, I will like its foreground to turn red.
Upvotes: 0
Views: 1976
Reputation: 128146
To my knowledge there is no equivalent to that state in WPF.
The WPF ListBoxItem has the states Unselected
, Selected
and SelectedUnfocused
in group SelectionStates
and the states Normal
, MouseOver
and Disabled
in group CommonStates
. States in each group are mutually exclusive, but states from different groups can be taken on simultaneously. The ListBoxItem can for example be in states Selected
and MouseOver
at the same time.
It is up to the control template to define a visualization that takes this fact into account. It could for example fill the item with a different background brush when it is selected, and draw an outer border when the mouse is over the item. The important thing is that there are independent visualizations that are visible at the same time, as the related states are independent and can be taken on at the same time. A user would typically become a bit confused when a selected list item doesn't look selected only because he moved the mouse over that item.
EDIT - ListBox example below. Could perhaps be done a lot easier with Triggers instead of Visual States.
<ListBox SelectionMode="Extended">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="LightGray" Margin="1">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="UnselectedText"
Storyboard.TargetProperty="Foreground.Color"
To="Blue" Duration="0:0:0.1"/>
<ColorAnimation Storyboard.TargetName="SelectedText"
Storyboard.TargetProperty="Foreground.Color"
To="Red" Duration="0:0:0.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="UnselectedText"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="SelectedText"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:0.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock Name="UnselectedText" Margin="2" Text="{TemplateBinding Content}">
<TextBlock.Foreground>
<SolidColorBrush Color="Black"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Name="SelectedText" Margin="2" Text="{TemplateBinding Content}" Opacity="0">
<TextBlock.Foreground>
<SolidColorBrush Color="White"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Items>
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
<ListBoxItem Content="Item 3"/>
<ListBoxItem Content="Item 4"/>
<ListBoxItem Content="Item 5"/>
<ListBoxItem Content="Item 6"/>
<ListBoxItem Content="Item 7"/>
<ListBoxItem Content="Item 8"/>
<ListBoxItem Content="Item 9"/>
<ListBoxItem Content="Item 10"/>
</ListBox.Items>
</ListBox>
Upvotes: 1