【问题标题】:WPF: Focus in a Window and UserControlWPF:聚焦在窗口和用户控件中
【发布时间】:2011-01-23 18:38:10
【问题描述】:

我正在尝试让 UserControl 正确地使用标签,但我很困惑。逻辑树如下所示。

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

Everything works fine, except when the visibility converter for the ComboBox returns Visibility.Collapsed (don't allow user to change database mode), then when textbox1 is selected, instead of being able to tab through the controls in the 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" />

【问题讨论】:

    标签: wpf xaml focus tabindex keyboard-navigation


    【解决方案1】:

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

    1. 删除 FocusManager.FocusedElement... ComboBox 是其中的第一个控件。
    2. 删除 FocusManager.IsFocusScope... 我想如果每次您输入用户控件时,其中的第一个控件将被聚焦,而不是您之前离开它时聚焦的那个,那是可以的。只需让用户控件“内联”在周围的控件中即可。
    3. 删除 UserControl 中的显式 TabIndices。您的布局已经暗示了相同的顺序。

    如果您消除了这三个复杂的因素,您可能已经完成了。 也许您还必须设置您的 UserControl Focusable=False, s.t.焦点被传递给组合框或 TextBox1 内的第一个可聚焦控件。

    【讨论】:

      【解决方案2】:

      我知道这个回复已经很晚了……但是你试过了吗:

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多