繁体   English   中英

将焦点设置在 WPF 中的父 TabItem 上

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM