0

我正在尝试让 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, the focus shifts to a button在窗口底部声明。除了显示的控件之外,没有其他任何东西都设置了 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" />
4

2 回答 2

5

我知道这个回复已经很晚了......但你有没有试过:

<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-05-13T22:52:34.263 回答
0

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

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

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

于 2010-03-26T07:51:35.717 回答