2010-03-04 105 views
0

我試圖讓一個用戶控件到標籤正確和感到莫名其妙。邏輯樹看起來像這樣。WPF:Focus在一個窗口,用戶控件

|-Window 
    -Grid 
    -TabControl 
     -TabItem 
     -StackPanel 
      -MyUserControl 
      |-StackPanel 
       -GroupBox 
       -Grid 
        -ComboBox 
        -Textbox1 
         -Textbox2 

一切正常,當組合框的知名度轉換器返回Visibility.Collapsed(不允許用戶更改數據庫模式)以外,那麼當TextBox1的選擇,而不是通過在控件能夠標籤, UserControl,焦點轉移到在窗口底部聲明的按鈕。除了顯示的控件外,沒有其他設置了TabIndex或FocusManager屬性。

我敲我的頭撞牆,我必須失去了一些東西。我已經嘗試過IsFocusScope = True/False,使用FocusedElement播放,如果該組合框不可見,則不起作用(Visibility.Collapsed)。

<Window x:Class="MyNamespace.Client.WinInstaller" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    FocusManager.FocusedElement="{Binding ElementName=tabWizard}"> 
    <Window.Resources> 
     <props:Settings x:Key="settings" /> 
    </Window.Resources> 
    <Grid Grid.IsSharedSizeScope="True"> 
     <!-- row and column definitions omitted --> 

     <loc:SmallHeader Grid.Row="0" x:Name="headerBranding" HeaderText="Setup" /> 
     <TabControl x:Name="tabWizard" DataContext="{StaticResource settings}" SelectedIndex="0" FocusManager.IsFocusScope="True"> 
      <TabItem x:Name="tbStart" Height="0"> 
       <StackPanel> 
        <TextBlock Text="Database Mode"/> 
        <loc:DatabaseSelector x:Name="dbSelector" AllowChangeMode="False" TabIndex="1" 
              AvailableDatabaseModes="SQLServer" IsPortRequired="False" 
              DatabaseMode="{Binding Default.DbMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
              DatabasePath="{Binding Default.DatabasePath,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
       </StackPanel> 
      </TabItem> 
     ... 

用戶控件的頂部低於:

<UserControl x:Class="MyNamespace.Client.DatabaseSelector" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Name="root" 
    FocusManager.IsFocusScope="True" 
    FocusManager.FocusedElement="{Binding ElementName=cboDbMode}"> 
    <UserControl.Resources> 
     <conv:DatabaseModeIsFileBased x:Key="DatabaseModeIsFileBased"/> 
     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> 
    </UserControl.Resources> 
    <StackPanel DataContext="{Binding}"> 
     <GroupBox> 
      <Grid> 
       <!-- row and column definitions omitted --> 
       <Label Content="Database Mode"/> 
       <ComboBox x:Name="cboDbMode" SelectedValue="{Binding ElementName=root,Path=DatabaseMode,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
          DisplayMemberPath="Value" SelectedValuePath="Key" TabIndex="1" Visibility="{Binding AllowChangeMode,ElementName=root,Converter={StaticResource BooleanToVisibilityConverter}}" /> 
        <!-- AllowChangeMode is a DependencyProperty on the UserControl --> 
       <Grid><!-- row and column definitions omitted --> 
        <Label "Host"/> 
        <TextBox x:Name="txtDBHost" Text="{Binding ElementName=root,Path=DatabaseHost,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TabIndex="2" /> 
        <TextBox x:Name="txtDBPort" Text="{Binding ElementName=root,Path=DatabasePortString,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" TabIndex="3" /> 

回答

0

也許問題是,你隱藏FocusManager.FocusedElement。 無論如何,你可以讓生活的只是消除了一些複雜因素,更容易:

  1. 刪除FocusManager.FocusedElement ... 組合框是內反正第一控制。
  2. 刪除FocusManager.IsFocusScope ... 我想如果每次進入用戶控件都可以,內部的第一個控件將會被聚焦,而不是在您之前離開它時被聚焦的那個控件。只需讓用戶控件在周圍的控件中「內聯」即可。
  3. 在用戶控件中刪除明確TabIndices。你的佈局已經意味着相同的順序。

如果消除這三個複雜的因素,你可能已經完成了。 也許你也必須設置你的UserControl Focusable = False,s.t.將焦點傳遞給comboBox或TextBox1中的第一個可聚焦控件。

4

我知道這反應相當晚了......但你嘗試過:

<UserControl ... KeyboardNavigation.TabNavigation="Local"> 

這樣做將確保一旦你的用戶控件已收到焦點時,您將您的用戶控件內只有通過導航接受tab(而不是杞人憂天關於整個應用程序中衝突的TabIndex值)。在遍歷UserControl的TabStops之後,TabNavigation將恢復到TabStop的外部。

http://msdn.microsoft.com/en-us/library/system.windows.input.keyboardnavigationmode.aspx

相關問題