2017-05-25 66 views
0

如果我有一个窗口的UI来自控件模板,则显示键盘焦点的虚线(“焦点视觉”)不显示。如果我使用直接内容而不是控件模板来实现,那么焦点视觉效果很好。没有显示带控制模板窗口的焦点虚线

任何人都知道如何使用控件模板时有焦点视觉?

我最初使用XAML,但为了排除它,我在C#中做了演示代码。我也很满意基于XAML的解决方案。

enter image description here

的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

我刚刚推出的自定义窗口从主窗口...

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     (new Class1()).Show(); 
     (new Class2()).Show(); 
    } 
} 

回答

2

我认为这个问题造成的,因为存在Class1窗口的可视树没有装饰器层,但有在Class2窗口的可视树。

previous visual tree

当一个框架元素获得键盘焦点,似乎它试图通过装饰器层分配对焦的视觉风格。 (参考:用于FrameworkElement的源代码,并KeyboardNavigation

选项#1简单的解决办法是改变你的代码,在代码中加入一个ContentControl(并重新模板吧):

public Class1() 
{ 
    Title = "Class1"; 
    Height = 150; 
    Width = 300; 

    Content = new ContentControl 
    { 
     Template = new ControlTemplate() 
     { 
      VisualTree = new FrameworkElementFactory(typeof(Template1)) 
     } 
    }; 
} 

而新的视觉树具有装饰器层,因此焦点视觉样式:

new visual treevisual style

选项#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" }, 
        } 
       } 
      } 
     ); 
    } 
} 

注:我不知道是什么原因装饰器默认情况下,当你重新加入模板a 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> 
+1

大答案沙拉达普拉,你明白了吧! –

+1

谢谢!我想知道AdornerDecorator的用途。 – Vimes