2010-03-04 2 views
0

Я пытаюсь правильно настроить UserControl для вкладок и сбивать с толку. Логическое дерево выглядит так.WPF: Фокус в окне и UserControl

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

Все работает отлично, за исключением того, когда видимость конвертер для ComboBox возвращает Visibility.Collapsed (не позволяет пользователю изменять режим базы данных), то при выборе TextBox1, вместо того, чтобы быть в состоянии вкладки с помощью элементов управления в UserControl, фокус переходит на кнопку, объявленную в нижней части окна. Ничто иное, кроме отображаемых элементов управления, не имеет свойств TabIndex или FocusManager.

Я стучу головой о кирпичную стену, и я должен что-то упустить. Я пробовал IsFocusScope = True/False, играл с FocusedElement, и ничего не работает, если этот ComboBox невидим (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 ... Я полагаю, это нормально, если каждый раз, когда вы входите в usercontrol, первый элемент управления внутри будет сосредоточен, а не тот, который был сфокусирован, когда вы его покинули раньше. Просто позвольте usercontrol быть «встроенным» в окружающие элементы управления.
  3. Удалить явные TabIndices в UserControl. В вашем макете подразумевается тот же порядок.

Если вы устраните эти три осложняющих фактора, возможно, вы уже можете это сделать. Возможно, вам также необходимо установить UserControl Focusable = False, s.t. основное внимание уделяется первому сосредоточенному контролю внутри - comboBox или TextBox1.

4

Я знаю, что этот ответ довольно поздно ... но вы пробовали:

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

Это обеспечит как только ваш UserControl уже получил фокус, вы будете ориентироваться только через TabStop в вашем UserControl (вместо worring о конфликтующих значениях TabIndex во всем приложении). После перехода через TabStops вашего UserControl, TabNavigation вернется к TabStop за его пределами.

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

Смежные вопросы