c# - 在 WPF 中将焦点设置在父 TabItem 上
问题描述
有没有办法自动切换到承载我想要关注的控件的 TabItem?
我的示例窗口来举例说明这个问题。
<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
但要使其正常工作,我必须先选择TabItem2
。在提供的示例中,这显然很容易,但我正在寻找一种自动化解决方案,它“知道”SomeTextBox
属于TabItem2
并切换到它,然后将重点放在所需的控件上。不用说,在实际情况下,SomeTextBox
可能在VisualTree
其他类型的窗格中的其他级别。可能吗?
顺便说一句,如果有帮助,此类功能的应用会将焦点设置在由错误验证突出显示的控件上和/或切换到包含它的窗格。
解决方案
您可以使用VisualTreeHelper
该类来查找特定类型的最近父级。
这是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
,你就可以设置它的IsSelected
属性来选择它TabControl
。
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();
}
推荐阅读
- typescript - 具有通用返回类型的打字稿函数
- python - 如何 cv2.imshow 大尺寸图像?
- python - 积分逼近python
- scala - 在Scala中将循环问题转换为递归解决方案
- c - 奇怪的 printf 行为
- swift - MPVolumeView 拇指图像未正确水平绘制
- database - FileMaker Pro 数据库引擎
- javascript - 使用 AngularJS 进行多页应用程序
- reactjs - 第 3:13 行:在 React.js 中使用 Chartjs-2 时定义了“缩放”但从未使用过 no-unused-vars
- reactjs - 如何重新渲染或多次调用屏幕反应原生