如果我有一个窗口,其UI来自控件模板,则显示键盘焦点的虚线("焦点视觉")不会显示。如果我重新实现使用直接内容而不是控件模板,那么焦点视觉效果很好。
任何人都知道在使用控件模板时如何使焦点可视化?
我最初使用的是XAML,但为了排除它,我在C#中编写了演示代码。我也对基于XAML的解决方案感到满意。
的Class1.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
class Class1 : Window
{
public Class1()
{
Title = "Class1";
Height = 150;
Width = 300;
Template = new ControlTemplate() {
VisualTree = new FrameworkElementFactory(typeof(Template1))
};
}
class Template1 : StackPanel
{
public Template1()
{
Background = Brushes.White;
Children.Add(new TextBox());
Children.Add(new Button() { Content = "button 1" });
Children.Add(new Button() { Content = "button 2" });
}
}
}
Class2.cs
using System.Windows;
using System.Windows.Controls;
class Class2 : Window
{
public Class2()
{
Title = "Class2";
Height = 150;
Width = 300;
Content = new StackPanel
{
Children =
{
new TextBox(),
new Button() { Content = "button 1" },
new Button() { Content = "button 2" },
}
};
}
}
MainWindow.cs
我刚刚从MainWindow启动了自定义窗口......
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
(new Class1()).Show();
(new Class2()).Show();
}
}
答案 0 :(得分:2)
我认为这个问题是因为Class1
窗口的可视化树中没有adorner-layer,而是Class2
窗口的可视化树。
当一个framework-element获得键盘焦点时,它似乎试图通过一个adorner-layer分配焦点视觉风格。 (参考: FrameworkElement
和KeyboardNavigation
的源代码)
选项#1 最简单的解决方案是更改代码,在代码中包含ContentControl
(并重新模板化):
public Class1()
{
Title = "Class1";
Height = 150;
Width = 300;
Content = new ContentControl
{
Template = new ControlTemplate()
{
VisualTree = new FrameworkElementFactory(typeof(Template1))
}
};
}
新的视觉树具有装饰层,因此具有焦点视觉风格:
选项#2 或者,另一种解决方案是确保您的模板有AdornerDecorator
- more details here
class Template1 : Grid
{
public Template1()
{
Background = Brushes.White;
Children.Add(
new AdornerDecorator()
{
Child = new StackPanel
{
Children =
{
new TextBox(),
new Button() { Content = "button 1" },
new Button() { Content = "button 2" },
}
}
}
);
}
}
注意:我不确定为什么在重新模板ContentControl
时默认添加装饰器,而不是Window
的情况。
更新05/25:我们意识到,我们在使用ContentControl
自定义模板时看到的装饰器来自Window
的默认模板。
选项#3 如果您在XAML中进行操作,只需将元素包装在<AdornerDecorator>
中:
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<AdornerDecorator>
<StackPanel>
<TextBox/>
<Button Content="Button 1"/>
<Button Content="Button 2"/>
</StackPanel>
</AdornerDecorator>
</ControlTemplate>