2013-05-07 91 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