在我正在处理的控件中,当项目被聚焦时,默认焦点矩形跨越整个行及其所有可见子项。我知道如何隐藏它。但是当项目具有键盘焦点时,我仍然需要这样的焦点指示器。我已经了解了IsKeyboardFocused属性,但是当鼠标单击该项时也是如此。所以我想我需要以某种方式使用FocusVisualStyle。但我无法弄清楚如何。
这是默认焦点的样子:
这就是它应该的样子:
这是我的控件模板的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或任何东西,它应该是可见的。但我没有设法做到这一点。它可以在任何焦点上显示,也可以从不显示。
答案 0 :(得分: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}" />
同样的IsKeyboardMode属性被添加到TreeViewEx父控件中,这就是我的魔力:
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");
}
}
这会对键盘和鼠标的预览事件做出反应,以设置适当的输入模式。仅当最后一个输入来自键盘时,焦点矩形才可见。