WPF:专注于窗口和UserControl

时间:2010-03-04 16:52:17

标签: wpf xaml focus tabindex keyboard-navigation

我正在尝试将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" />

2 个答案:

答案 0 :(得分:4)

我知道这个回复已经很晚了......但你试过了吗?

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

这样做将确保一旦您的UserControl已经收到焦点,您将只在UserControl中通过TabStop导航(而不是担心整个应用程序中的TabIndex值冲突)。循环浏览UserControl的TabStop后,TabNavigation将恢复到其外部的TabStop。

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

答案 1 :(得分:0)

也许问题是你隐藏了FocusManager.FocusedElement。 无论如何,只要消除一些复杂的因素,你就可以让生活更轻松:

  1. 删除FocusManager.FocusedElement ... 无论如何,ComboBox是第一个控件。
  2. 删除FocusManager.IsFocusScope ... 我想如果每次进入用户控件时都可以对焦,那么第一个控件将被聚焦,而不是之前离开时聚焦的对象。只需让用户控件在周围的控件中“内联”。
  3. 删除UserControl中的显式TabIndices。您的布局已经暗示了相同的顺序。
  4. 如果消除这三个复杂因素,您可能已经完成了。 也许你还必须设置你的UserControl Focusable = False,s.t。焦点将传递给 - comboBox或TextBox1中的第一个可聚焦控件。