次のような ListBoxItem のスタイルがあり、listBoxItem が前述の VisualState のままである場合に「フォーカス」視覚効果が失われるという問題があります。「フォーカスされた」ListBoxItemに適切な視覚効果を強制的に表示するにはどうすればよいですか?
バグを達成するシナリオ:
1) ListBoxItem をクリックします -> フォーカスとスタイルを受け取ります (ok)。
2) ポインターをこの ListBoxItem の上に移動します -> まだフォーカスがあり、「MouseOver」のスタイルを受け取ります (ここで提案されているように、別の VisualStateGroup 'CommonStates' 内にあります: https://msdn.microsoft.com/en-us/library /system.windows.controls.listboxitem%28v=vs.95%29.aspx )(わかりました).
3) マウスを ListBoxItem の境界から離す -> MouseOver(ok) のスタイルを失います。
4) 現在、ListBoxItem は「CommonStates」の「Normal」状態であり、「Focused」でもありますが、「Focused」のスタイリッシュさがありません (これは私の問題です)。
5) この ListBoxItem をクリックしようとしても効果がない
どう対処すればよいか、アドバイスをいただけないでしょうか。
Silverlight を使用しているため、トリガーは禁止されています。
これが私のスタイルです:
<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>
VisualStateGroup を「FocusStates」から SelectionStates に変更すると、同じように動作します。ユーザーがどこかをクリックし、別のコントロールにも同様の境界線がある場合、UI に視覚的な不一致が生じる可能性があるため、選択ではなくフォーカスに関連付けたいと考えています。
ところで:私が読んだ別のmsdnサイトで:「コントロールは、そのControlTemplateで定義されている各VisualStateGroupに対して常に1つの状態にあり、同じVisualStateGroupから別の状態になったときにのみ状態を離れます。」コード ビハインドから、listBoxItem がまだフォーカスされていることを確認しました。その上、マウスが listBoxItem を離れた後、その状態に強制しようとしていましたが、結果はありませんでした (簡略化: ActiveViewDefinition は、リストボックス内の実際にフォーカスされた項目の代わりです):
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);
}
}