2013-05-07 46 views
5

我正在开发一个派生自Control的自定义控件,并使用ControlTemplate进行了定义。剔除所有花里胡哨后,控制显示只有四个文本框:如何防止使用控件模板创建的WPF自定义控件从围绕自身绘制焦点?

<Style TargetType="{x:Type local:MyControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:MyControl}"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBox/> 
        <TextBox/> 
        <TextBox/> 
        <TextBox/> 
       </StackPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

的问题是,控制能够接收键盘焦点和绘制焦点矩形围绕自身(文本框的不是一个,但在他们周围)。在浏览窗口中的控件时,这会添加一个不必要的制表位。

设置Focusible为false上的自定义控制(使用风格的setter)解决了这个问题,但这样的解决方案是远远不够完善,因为使用该控件的开发人员可以设置Focusible为true这会毁了制表位行为。

我可以对控件的GotKeyboardFocus事件作出响应,并在整个控件接收焦点时将焦点放在第一个TextBox上,但在Tab键后退时(使用Shift + Tab)时无法正常工作,第一个TextBox将在这种情况下,最后一个TextBox应该首先关注。

我怎样才能防止整个自定义控件接受键盘焦点,但允许子文本框作为制表符正常行事?

+1

不得不尝试了'FocusVisualStyle'设置为'null'? – 2013-05-07 14:28:24

+1

不幸的是,它不起作用,它只是在不改变行为的情况下隐藏选择矩形,用户必须按两次Tab才能到达第一个TextBox。 – RaceRalph 2013-05-07 15:45:22

+1

也将'Focusable'设置为'false'。其他一些开发者将其设置为“真”是他们的问题。实际上,您应该重写'FocusableProperty'的元数据,使其默认为'false'来控制。 – 2013-05-07 15:59:37

回答

0

我会创建一个实际的UserControl并封装聚焦管理。因为Xaml'ing通过风格只有你到目前为止......

这是一个UserControl +它的使用/测试在主窗口中的快速样本。正如你会注意到聚焦的矩形不再出现。为了简便起见,我没有包含数据绑定/视图模型等(如你的”问题不是有关)上visiblitychanged在代码中的第一个文本框后面

namespace WpfApplication1 
{ 
public partial class MyControl : UserControl 
{ 
    private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     if (IsVisible && IsEnabled) 
     { 
      Keyboard.Focus(null); 
      Keyboard.Focus(txtA); 
     } 
    } 

    public MyControl() 
    { 
     InitializeComponent(); 
    } 
} 

<UserControl x:Class="WpfApplication1.MyControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     IsVisibleChanged="OnIsVisibleChanged" > 
<StackPanel Orientation="Horizontal"> 
    <TextBox x:Name="txtA">txtA</TextBox> 
    <TextBox>txtB</TextBox> 
    <TextBox>txtC</TextBox> 
    <TextBox>txtD</TextBox> 
</StackPanel> 

将焦点

}

在我的小测试

,我把MyControl两者之间的其他textbozes,只运行选项卡时:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:c="clr-namespace:WpfApplication1" 
    Title="MainWindow" Height="350" Width="525"> 

<StackPanel> 
    <TextBox>txt1</TextBox> 
    <c:MyControl/> 
    <TextBox>txt2</TextBox> 
</StackPanel> 

+1

这似乎是一个好主意!我现在很忙,下周我会回到你的答案。 – RaceRalph 2013-08-02 14:12:35