Wpf 阻止较低z索引控件的选项卡导航

Wpf 阻止较低z索引控件的选项卡导航,wpf,xaml,Wpf,Xaml,我有下一个xaml: <Grid> <local:MyControl1 Grid.Row="0" Panel.Z-Index="1" /> <local:MyControl12 Grid.Row="1" Panel.Z-Index="1" /> <local:MyControl21 Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="2" /> <local:MyControl22 Grid

我有下一个xaml:

<Grid>
  <local:MyControl1 Grid.Row="0" Panel.Z-Index="1" />
  <local:MyControl12 Grid.Row="1" Panel.Z-Index="1" />
  <local:MyControl21 Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="2" />
  <local:MyControl22 Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="3" />
</Grid>

当显示
MyControl21
时,它将显示在
MyControl1
MyControl12
下。 当显示
MyControl22
时,它位于
MyControl1
MyControl12
MyControl21

当我使用
MyControl22
上的选项卡时,我想只选择
MyControl22
子控件。但看起来制表法也从
MyControl21
MyControl1
MyControl12
中选择较低级别的控件

如何防止较低级别上的选项卡选择控件?

您可以使用附加属性

让我们看一个例子:

<Grid>
    <local:UserControl1 x:Name="uc1" Panel.ZIndex="1" 
                        KeyboardNavigation.TabNavigation="{Binding ElementName=uc2, Path=Visibility, Converter={StaticResource TabNavConverter}}" />
    <local:UserControl2 x:Name="uc2" Panel.ZIndex="2" />
</Grid>

其中,
TabNavConverter
是一个
IValueConverter
,当
uc2
折叠或可见时返回

我希望它能有所帮助。

您可以使用附加属性

让我们看一个例子:

<Grid>
    <local:UserControl1 x:Name="uc1" Panel.ZIndex="1" 
                        KeyboardNavigation.TabNavigation="{Binding ElementName=uc2, Path=Visibility, Converter={StaticResource TabNavConverter}}" />
    <local:UserControl2 x:Name="uc2" Panel.ZIndex="2" />
</Grid>

其中,
TabNavConverter
是一个
IValueConverter
,当
uc2
折叠或可见时返回


我希望它能有所帮助。

这里没有很多好的通用选项。据我所知,
KeyboardNavigation
中没有根据
ZIndex
自动跳过控件的设置。因此,很难找到一种自动适用于所有不同组合的
ZIndex
值(自动确定顶部控件)的解决方案。我认为最好的选择是基于样式触发器修改
IsTabStop
属性

<Style TargetType="Control" x:Key="TabStopStyle">
   <Style.Triggers>
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Panel.ZIndex)}" Value="3">
         <Setter Property="KeyboardNavigation.IsTabStop" Value="True"/>
      </DataTrigger>
   </Style.Triggers>
   <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
</Style>

不幸的是,由于控件的类型各不相同,因此必须明确设置每个控件的样式:

  <local:MyControl22 Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="3" Style="{StaticResource TabStopStyle}"/>


本例假设顶部控件的
ZIndex
为3。一般来说,将top控件设置为更高的ZIndex(如100)可能会有所帮助,这样,如果添加更多控件,就不必更改触发规则。

这里没有很多好的常规选项。据我所知,
KeyboardNavigation
中没有根据
ZIndex
自动跳过控件的设置。因此,很难找到一种自动适用于所有不同组合的
ZIndex
值(自动确定顶部控件)的解决方案。我认为最好的选择是基于样式触发器修改
IsTabStop
属性

<Style TargetType="Control" x:Key="TabStopStyle">
   <Style.Triggers>
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Panel.ZIndex)}" Value="3">
         <Setter Property="KeyboardNavigation.IsTabStop" Value="True"/>
      </DataTrigger>
   </Style.Triggers>
   <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
</Style>

不幸的是,由于控件的类型各不相同,因此必须明确设置每个控件的样式:

  <local:MyControl22 Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="3" Style="{StaticResource TabStopStyle}"/>


本例假设顶部控件的
ZIndex
为3。为了概括这一点,可以将top控件设置为更高的
ZIndex
(如100)因此,如果添加了更多控件,则不必更改触发规则。

请注意:附加到
MyControl22
并设置为
false
KeyboardNavigation.IsTabStop
属性不会阻止其子项被停止。@IlVic这是真的-我假设
MyControl22
已停止无子控件。如果特定的自定义控件需要,我猜
TabNavigation
属性可能也可以从样式触发器设置。请注意:附加到
MyControl22
KeyboardNavigation.IsTabStop
属性并设置为
false
不会阻止其子项被删除tabstopped.@IlVic这是真的-我假设MyControl22没有子控件。我想如果特定的自定义控件需要
TabNavigation
属性,那么也可以从样式触发器中进行设置。