2017-10-09 85 views
2

好吧,我知道這個標題看起來像它有所有答案,但沒有在這裏找到答案爲我工作。所以,在這裏。WPF每個TabItem的初始焦點

我有這樣的佈局:

<Window> 
    <Grid> 
    <DockPanel> 
     <TabControl> 
     <TabItem> 
      <Page x:Name="p"> 
      <Grid x:Name="g2"> 
       <TabControl x:Name="tc"> 
       <TabItem x:Name="ti1"> 
        <StackPanel x:Name="sp"> 
        <C:TextBox x:Name="txt"/> 
        </StackPanel> 
       </TabItem> 
       <TabItem x:Name="ti2"> 
        <C:DataGrid x:Name="dg"/> 
       </TabItem> 
       </TabControl> 
      </Grid> 
      </Page> 
     </TabItem> 
     </TabControl> 
    </DockPanel> 
    </Grid> 
</Window> 

現在,我的目標是當ti2TabItem被選中時ti1TabItem被選擇把重點放在txtTextBoxdgDataGrid。另外,我真的很喜歡在XAML中設置它。

注意:我只能使用在這裏命名的控件,所以直到Page控件。

有什麼我試過到目前爲止:

  • 設置上的所有父控件的FocusManager.FocusedElement="{Binding ElementName=txt}"txtControl的父樹(直到Page)。
  • 設置FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"txtdg控件。
  • 通過設定焦點在代碼TabControlSelectionChanged事件:

    • 如果(ti1.IsSelected) { tc.UpdateLayout(); FocusManager.SetFocusedElement(sp,txt); }
    • 如果(ti1.IsSelected) { tc.UpdateLayout(); txt.Focus(); }

TextBoxDataGrid創建控件一樣UserControl S,但實際上是繼承TextBoxDataGrid,像這樣的類:

<TextBox ... </TextBox> 

public partial class TextBox : System.Windows.Controls.TextBox 

由於我說,XAML解決方案是需要的,但如果前者不可行,我也會解決一個代碼。

+0

很高興看到每次嘗試的結果(又名發生了什麼)。既然你嘗試了最明顯的,那麼讓[mcve](https://stackoverflow.com/help/mcve)僅僅複製和播放會很好。 – Sinatr

+0

@Sinatr我會稍後嘗試,當有更多的時間,但現在我可以說,除了'SetFocusedElement'之外,所有的解決方案都沒有任何效果。但是使用'FocusManager'在'TextBox'中產生了可見的'Caret',但是焦點不在那裏,我無法輸入。而且這隻在頁面初始打開時起作用,當我選擇其他選項卡時,並且回到第一個選項卡時,即使是'Caret'也不可見。 – Adder

+0

@Adder,請不要大幅編輯其他人的答案以包含其他信息。在你的具體情況下,我建議你投票選出有幫助的答案(如果你喜歡的話),併發布你自己的答案和附加信息並接受它。請參閱:https://stackoverflow.com/help/self-answer – Alex

回答

0

好吧,分派部分來自Keyur Patel的答案是該解決方案我,雖然不是完整的。我的答案是用Dispatcher更新TabControl佈局,並調用FocusDispatcher。所以,對我來說,完整的回答是:

Dispatcher.BeginInvoke((Action) (() => tc.UpdateLayout())); 
Dispatcher.BeginInvoke((Action) (() => txt.Focus())); 

,或者你可以只使用Invoke相反,對於UI線程等待您的Action

因爲我不得不使用Dispatcher的原因,這是因爲我使用它來首先更改選定的選項卡。至少,這是我最好的猜測。

+1

啊,很高興你把它弄到底:) –

1

你可以嘗試類似代碼隱藏解決方案,但這種變異的東西:

<TabControl x:Name="tc" SelectionChanged="tc_selectionChanged"> 

,並在後面的代碼:

InitializeComponent(); 

//if you know which control to focus by default when page is first loaded 
Dispatcher.BeginInvoke(new Action(() => { txt.Focus(); })); 

private void tc_selectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (ti1.IsSelected) 
    { 
     txt.Focus(); 
    } 
    else if (ti2.IsSelected) 
    { 
     dg.Focus(); 
    } 
} 

我想這在我自己的WPF應用程序上精確設置,所以我知道它的工作原理

幫助鏈接:

WPF TabControl On SelectionChanged, set focus to a text field

How to focus control in the tabItem ın WPF(雖然這對我來說工作沒有UpdateLayout()

+0

這不適合我。 'Caret'是可見的,但重點不在'TextBox'上。 [圖片的文本框](https://postimg.org/image/41j8drx9vv/) – Adder

+0

@Adder有趣的是,我有完全相同的問題(凍結插入是可見的,但打字的東西顯示焦點不在文本框)但我得到它與Dispatcher.BeginInvoke行(新行動(()=> {txt.Focus();}));''。你能否確認你在'InitializeComponent();'後面的代碼後面調用它? –

+0

可能嘗試'FocusManager.SetFocusedElement(txt,txt)'而不是'txt.Focus()' – grek40