我正在编写一个带有允许多选的列表框的应用程序(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/

    10-13 07:41