我正在编写一个带有允许多选的列表框的应用程序(SelectionMode=Multiple); lisbox 中的项目是配方的成分。
不幸的是,单击列表框项目会选择该项目,这可能不是您想要的。我想要以下场景:
我所做的是设置 ListBoxItem 的样式以包含一个复选框和一个 ContentPresenter(如 in this blog )。
不过,单击成分名称会将其选中。
因此,我在包含成分名称的文本块上捕获 MouseDown 事件,找到底层 ListBoxItem,对其调用 Focus() 并将事件的 Handled 属性设置为 true。
现在,列表框项具有焦点但未被选中。使用向上和向下键显示焦点在正确的项目上。
我的问题是用户看不到他点击了正确的项目。此项目上未显示虚线矩形。
结果如下:
这是我想要的:
我试过调用私有(private) WPF 方法,如 KeyboardNavigation.ShowFocusVisual,我试过将击键发送到列表框(当由人类完成时,按右光标键或 Alt 键使虚线矩形出现)。
任何想法 ?
最佳答案
SendInput 是我发现的唯一一种解决方法。来自 this 链接。
使用它的一种简单方法是使用 CodePlex 的 InputSimulator。
添加对 InputSimulator.dll 的引用,我们可以做这样的事情
private bool m_waitingForFocusVisualStyle = false;
private void ListBoxItem_GotFocus(object sender, RoutedEventArgs e)
{
if (m_waitingForFocusVisualStyle == false)
{
m_waitingForFocusVisualStyle = true;
InputSimulator.SimulateKeyDown(VirtualKeyCode.TAB);
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, VirtualKeyCode.TAB);
}
else
{
m_waitingForFocusVisualStyle = false;
}
}
但是由于很多原因,这可能并不理想(例如,将 Shift+Tab 切换到 ListBoxItem)
一个更好的主意可能是删除 ListBoxItem 的 FocusVisualStyle 并像这样在 ControlTemplate 中添加您自己的。 (从 Blend 复制并从标准 FocusVisualStyle 添加了“FocusVisualStyle”)
<ListBox ...>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template" Value="{StaticResource ListBoxItemTemplate}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ControlTemplate x:Key="ListBoxItemTemplate" TargetType="{x:Type ListBoxItem}">
<Grid>
<Rectangle Grid.ZIndex="1"
Name="focusVisualStyle"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="true"
Visibility="Hidden"/>
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="focusVisualStyle" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
关于WPF:如何以编程方式提供键盘焦点位于列表框中的视觉反馈?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4238790/