将焦点矩形应用于子元素

3
在我当前正在处理的控件中,当某个项目被聚焦时,默认的焦点矩形框跨越整行和所有可见的子项目。我知道如何隐藏它,但是当该项目有键盘焦点时,仍然需要这样的焦点指示器。我已经阅读了IsKeyboardFocused属性,但是当用鼠标单击该项时,它也会为真。所以我想我需要以某种方式使用FocusVisualStyle。但我无法弄清楚如何使用。
以下是默认焦点的外观: enter image description here 以下是它应该显示的内容: enter image description here 以下是控件模板的XAML代码:
<Border ...>
    <ContentPresenter FocusManager.IsFocusScope="True"
        Content="{TemplateBinding HeaderedContentControl.Header}"
        ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
        ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
        ContentSource="Header"
        Name="PART_Header" .../>
</Border>
<!-- Additional border glare inside the item -->
<Border BorderThickness="1" BorderBrush="#80ffffff" Margin="1"
    SnapsToDevicePixels="True" CornerRadius="2"/>
<!-- Focus rectangle inside the item -->
<Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="Black"
    SnapsToDevicePixels="True" Margin="2"
    Visibility="Hidden" Name="FocusRectangle"
    FocusVisualStyle="{StaticResource FocusStyle}"/>

我的XAML中已经有一个默认情况下不可见的焦点矩形。通过FocusVisualStyle或其他方式,它应该变得可见。但是我没有成功做到这一点。要么在任何焦点下都可见,要么从未出现过。

1个回答

0

我已经找到了一个解决问题的方法。它看起来对我来说是一样的,但我不完全确定这是否是正确的方法。我正在使用上面的FocusRectangle并自行处理其显示和隐藏。

这是管理焦点矩形可见性的触发器:

<!-- Show the focus rectangle when the item is focused -->
<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="Controls:TreeViewExItem.IsKeyboardMode" Value="True"/>
    <Condition Property="Controls:TreeViewExItem.IsFocused" Value="True"/>
  </MultiTrigger.Conditions>
  <Setter TargetName="FocusRectangle" Property="Visibility" Value="Visible"/>
</MultiTrigger>

然后我已经向TreeViewExItem添加了一个新属性,指示最后的输入是来自鼠标还是键盘。这可能可以扩展到触摸或笔,但我没有这样的设备进行测试。

public static DependencyProperty IsKeyboardModeProperty =
    DependencyProperty.Register(
        "IsKeyboardMode",
        typeof(bool),
        typeof(TreeViewExItem),
        new FrameworkPropertyMetadata(false, null));

public bool IsKeyboardMode
{
    get
    {
        return (bool) GetValue(IsKeyboardModeProperty);
    }
    set
    {
        SetValue(IsKeyboardModeProperty, value);
    }
}

该属性通过绑定从父控件传递给每个项:

<!-- Pass on the TreeViewEx' IsKeyboardMode value to each item because
  we couldn't access it otherwise in the triggers -->
<Setter Property="IsKeyboardMode"
  Value="{Binding (Controls:TreeViewEx.IsKeyboardMode),
    RelativeSource={RelativeSource
      AncestorType={x:Type Controls:TreeViewEx}}, Mode=OneWay}" />

TreeViewEx父控件中添加了相同的IsKeyboardMode属性,这里就展现了我的魔力:

protected override void OnPreviewKeyDown(KeyEventArgs e)
{
    base.OnPreviewKeyDown(e);
    if (!IsKeyboardMode)
    {
        IsKeyboardMode = true;
        //Debug.WriteLine("Changing to keyboard mode from PreviewKeyDown");
    }
}

protected override void OnPreviewKeyUp(KeyEventArgs e)
{
    base.OnPreviewKeyDown(e);
    if (!IsKeyboardMode)
    {
        IsKeyboardMode = true;
        //Debug.WriteLine("Changing to keyboard mode from PreviewKeyUp");
    }
}

protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
    base.OnPreviewMouseDown(e);
    if (IsKeyboardMode)
    {
        IsKeyboardMode = false;
        //Debug.WriteLine("Changing to mouse mode");
    }
}

这个程序会根据键盘和鼠标的预览事件来设置适当的输入模式。只有最后一个输入是来自键盘时,焦点矩形才可见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接