I have the ListBoxItem's style as follows and a problem with loosing 'Focused' visual effects when the listBoxItem remains in mentioned VisualState. How to force appropriate visual effects to appear on ‘Focused’ ListBoxItem?
The scenario to achieve a bug:
1) Click the ListBoxItem -> it receive the focus and styles(ok).
2) Move the pointer over this ListBoxItem -> it’s still focused and receive the styles for ‘MouseOver’ (it is within a separate VisualStateGroup ‘CommonStates’ as suggested here: https://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem%28v=vs.95%29.aspx )(ok).
3) Make the mouse leave the ListBoxItem’s bounds -> it loses the style for MouseOver(ok).
4) Now, the ListBoxItem is in ‘Normal’ state of ‘CommonStates’ and is also ‘Focused’, but doesn’t have the stylish for ‘Focused’(it is my problem).
5) Attampting to click this ListBoxItem has no effect
Could you give me some advice, how to deal with it?
I’m using Silverlight, so triggers are forbidden 4 me.
Here is my style:
<Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="ContentControl.Foreground" Value="{StaticResource ViewModeButtonForeground}" />
<Setter Property="Focusable" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonForeground}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckOuterBorder" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonOuterBorder_MouseOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckOuterBorder" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonBackground_MouseOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonForeground_Focused}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckOuterBorder" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonOuterBorder_Focused}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckOuterBorder" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource ViewModeButtonBackground_Normal}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"></VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Border x:Name="CheckOuterBorder" CornerRadius="2" BorderThickness="1" BorderBrush="Transparent" Background="Transparent">
</Border>
<Grid x:Name="GridContent" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Left" Source="{Binding ImgSource, Mode=OneWay}"/>
<ContentControl x:Name="Content" Grid.Column="1" Margin="3,0,0,0" Foreground="{TemplateBinding Foreground}" Content="{Binding Title}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="Center" Width="Auto"/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ViewModeSelectionListBoxStyle" TargetType="ListBox">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="IsTabStop" Value="True" />
<Setter Property="ItemContainerStyle" Value="{StaticResource ListBoxItemStyle1}" />
<Setter Property="Focusable" Value="True" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
If I change my VisualStateGroup from ‘FocusStates’ into SelectionStates it behaves the same. I want it to be associated with focus rather than the selection, because there can be visual mismatch in the UI if user clicks somewhere and another control will have similar border too.
BTW: On another msdn site I’ve read: ‘The control is always in one state for each VisualStateGroup that is defined in its ControlTemplate and only leaves a state when it goes into another state from the same VisualStateGroup.’ From my code-behind I have ensured that the listBoxItem has still the focus on. Besides, I was trying to enforce going to that state after the mouse leaving my listBoxItem – with no results (simplifying: ActiveViewDefinition is an replacement for the actually focused item in the listbox):
private void It_MouseLeave(object sender, MouseEventArgs e)
{
ListBoxItem lbItem = sender as System.Windows.Controls.ListBoxItem;
if (lbItem != null && lbItem.Content == ActiveViewDefinition)
{
VisualStateManager.GoToState(lbItem, "Focused", true);
}
}