WPF:如何以编程方式提供键盘焦点位于列表框中的视觉反馈?

2024-03-14

我正在编写一个带有允许多项选择的列表框的应用程序(SelectionMode=Multiple); lisbox 中的项目是食谱的成分。

不幸的是,单击列表框项目会选择该项目,这可能是不需要的。我想要以下场景:

  • 用户单击列表框以选择列表框(列表框本身,而不是项目)
  • 用户滚动到正确的项目并选择它

我所做的是设置 ListBoxItem 的样式以包含一个复选框和一个 ContentPresenter (例如在这个博客中 http://alexshed.spaces.live.com/blog/cns!71C72270309CE838!133.entry)。 不过,单击成分名称即可将其选中。 因此,我在包含成分名称的文本块上捕获 MouseDown 事件,找到基础 ListBoxItem,对其调用 Focus() 并将事件的 Handled 属性设置为 true。

现在,列表框项目具有焦点但未被选中。使用向上和向下键表明焦点位于正确的项目上。 我的问题是用户看不到他点击了正确的项目。该项目上未显示虚线矩形。 结果如下:

这就是我想要的:

我尝试过调用私有 WPF 方法,例如 KeyboardNavigation.ShowFocusVisual,我尝试过将击键发送到列表框(当由人类完成时,按右光标键或 Alt 键会出现虚线矩形)。

任何想法 ?


SendInput 是我发现的唯一可以克服这个问题的方法。从this http://robrelyea.wordpress.com/2007/06/15/sendkeys-for-wpf/ link.

PInvoke 到 SendInput – 这是 模拟输入的官方方式。它 将输入推入所有的 预期的代码路径,并且是 与真实输入无法区分。

使用它的一个简单方法是输入模拟器 http://inputsimulator.codeplex.com/来自 CodePlex。

添加对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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF:如何以编程方式提供键盘焦点位于列表框中的视觉反馈? 的相关文章

  • 在 WPF 树视图中获取 FullPath?

    如果我以编程方式创建 WPF TreeView 例如 TreeView treeView lt added in the designer TreeViewItem rootNode new TreeViewItem rootNode He
  • 默认转换器何时启动?

    使用以下代码 虽然 Text 属性绑定到 DateTime 源属性 但我注意到 WPF 似乎会自动将文本转换为 DateTime 而无需我编写 ValueConverter 有人可以解释一下这是如何完成的吗
  • 与 wpf ComboBox DisplayMemberPath、SelectedValue 和 SelectedValuePath 混淆

    我一直在努力解决这些组合框属性 显示成员路径 选定值 选定的值路径 我正在构建一个主详细信息表单 组合框中充满了客户 用户在组合中选择客户 所有文本框 EG 均正确填写 我遇到的问题是我已经让它工作了 但我不理解这些属性和差异 有没有一个很
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • App 对象中的 Log4Net?

    我正在开始在 WPF 桌面应用程序中进行日志记录 使用 Log4Net 作为日志记录组件 这是我的问题 在一个简单的桌面应用程序中 是否有任何理由不将我的记录器实例化为 App 类 App xaml cs 的属性 就像这样 public p
  • 自动过滤/排序列表框项目 (Windows Phone)

    我想确保添加到列表框中的项目根据每个项目的序列号按升序排序 例如 1 项目 2 项目 4 项目 3 项目应根据其编号自动排序 1 2 3 10 这是 C 源代码 namespace XeroQuiz public partial class
  • 创建面向鼠标和触摸的 WPF 应用程序的最佳实践[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Relay/ICommand 与 DelegateCommand——差异

    据我所知 下面的代码可以从 Relay ICommand 命令更改为 Delegate 命令 并且仍然以相同的方式绑定命令 如果我错了 它们的区别和用途是什么 private DelegateCommand something public
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 我的 WPF 应用程序中的 SaveFileDialog 异常

    我的一位客户在保存文件时遇到 WPF 应用程序崩溃的情况 我的保存文件代码是 var saveFileDialog new SaveFileDialog InitialDirectory string Concat Environment
  • 如何禁用列表框上的突出显示但保留选择?

    我无法找到如何不允许我的列表框突出显示所选项目 我知道我没有添加触发器来突出显示该项目
  • 如何使用DocumentViewer显示流程文档?

    我的资源中有一个简单的流程文档 FlowDocument1 xaml
  • 如何更改 TextBox.Text 而不丢失 WPF 中的绑定?

    在 WPF 应用程序中 我正在创建一个设置窗口来自定义键盘快捷键 在文本框中 我处理 KeyDown 事件并将 Key 事件转换为人类可读的形式 以及我想要获取数据的形式 文本框声明如下
  • 当其源是 https uri 时如何使 wpf MediaElement 播放

    在 wpf 独立应用程序 exe 中 我在主窗口中包含了 MediaElement
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 如何使用 MVVM 打开和关闭新 Windows?

    对于 MVVM 和 WPF 什么是处理打开和关闭新窗口和对话框的好 直接方法 打开和关闭应该由 ViewModel 驱动 对吗 但 ViewModel 不应该知道视图 我通常为此使用接口 例如 如果我想在单独的窗口中编辑记录 我有一个接口
  • 如何在 wpf 应用程序的代码隐藏中创建集合视图源

    我有以下代码 public partial class MainWindow Window public MainWindow InitializeComponent var entities new DemoEntities var de
  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 从固定文档中删除页面?

    如何从固定文档中删除页面 我添加这样的页面 Add page to pageContent PageContent pageContent new PageContent IAddChild pageContent AddChild fix

随机推荐