[英]Set Focus on parent TabItem in WPF
有没有办法自动切换到承载我想要关注的控件的 TabItem?
我的示例 window 来举例说明这个问题。
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Sample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="80"/>
<Setter Property="Height" Value="24"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TabControl Grid.Row="0" Margin="10" Background="White">
<TabItem Header="TabItem1">
<Button x:Name="SomeButton" Content="Set Focus on TextBox" Width="120" Click="Button_Click"/>
</TabItem>
<TabItem Header="TabItem2">
<TextBox x:Name="SomeTextBox" Margin="10" Text="Sample text"/>
</TabItem>
</TabControl>
<StackPanel Grid.Row="1" Margin="10">
<Button Content="Cancel" HorizontalAlignment="Right" Click="Button_Click_1"/>
</StackPanel>
</Grid>
</Window>
以及背后的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SomeTextBox.Focus();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Close();
}
}
因此,当单击SomeButton
时,我想将焦点移到SomeTextBox
但要使其正常工作,我必须先到 select TabItem2
。 在提供的示例中这显然很容易,但我正在寻找一种自动化解决方案,它“知道” SomeTextBox
属于TabItem2
并切换到它,然后将焦点设置在所需的控件上。 不用说,在实际情况下SomeTextBox
可能位于VisualTree
的其他级别中的某种其他类型的窗格中。 可能吗?
顺便说一句,如果有帮助,此类功能的应用会将焦点设置在由错误验证突出显示的控件上和/或切换到包含它的窗格。
您可以使用VisualTreeHelper
class 来查找特定类型的最近父级。
这是This answer中的一个实现示例。
public static T FindParentOfType<T>(this DependencyObject child) where T : DependencyObject
{
DependencyObject parentDepObj = child;
do
{
parentDepObj = VisualTreeHelper.GetParent(parentDepObj);
T parent = parentDepObj as T;
if (parent != null) return parent;
}
while (parentDepObj != null);
return null;
}
获得对TabItem
的引用后,您可以在TabControl
中将其IsSelected
属性设置为 select 。
private void Button_Click(object sender, RoutedEventArgs e)
{
var tabItem = FindParentOfType<TabItem>(SomeTextBox);
if (tabItem is null) return;
(tabItem as TabItem).IsSelected = true;
SomeTextBox.Focus();
}
编辑
很好地捕捉到TextBox
不在可视树中,而其父TabItem
未被选中。 这是获取不依赖于可视化树的TextBox
的另一种方法。
private void Button_Click(object sender, RoutedEventArgs e)
{
FrameworkElement currentItem = SomeTextBox;
do
{
currentItem = (FrameworkElement)currentItem.Parent;
}
while (!(currentItem is TabItem)
&& (currentItem as TabItem).Parent != MyTabControl // Optional handling in case you have nested TabControls
&& !(currentItem.Parent is null));
(currentItem as TabItem).IsSelected = true;
currentItem.UpdateLayout();
SomeTextBox.Focus();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.