首页 文章

WPF:专注于窗口和UserControl

提问于
浏览
0

我正在尝试将UserControl正确地设置为标签并且感到困惑 . 逻辑树看起来像这样 .

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

一切正常,除非ComboBox的可见性转换器返回 Visibility.Collapsed (不允许用户更改数据库模式),然后选择textbox1,而不是能够通过UserControl中的控件切换,焦点转移到按钮在窗口底部声明 . 除了显示的控件之外,没有任何其他设置TabIndex或FocusManager属性 .

我_1115096已尝试过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 回答

  • 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

  • 0

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

    • 删除FocusManager.FocusedElement ...无论如何,ComboBox是第一个控件 .

    • 删除FocusManager.IsFocusScope ...我想如果每次进入用户控件时都可以对其中的第一个控件进行聚焦,而不是之前离开时聚焦的控件 . 只需让用户控件在周围的控件中"inlined"即可 .

    • 删除UserControl中的显式TabIndices . 您的布局已经暗示了相同的顺序 .

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

相关问题