WPF TabItems 没有父项

WPF TabItems have no parent

我通过绑定创建 TabItems 并尝试访问 TabItemDrop 中的 parent TabControl
但是,在放置事件的情况下,源中的父项始终是 null。如果我自己创建 TabItems,它仍然有效。

.xaml:

<TabControl ItemSource="{Binding TabItemList}">
    <TabControl.Resources>
        <Style TargetType="TabItem">
            <Setter Property="AllowDrop" Value="True" />
            <EventSetter Event="PreviewMouseMove" Handler="TabItemPreviewMouseMove" />
            <EventSetter Event="Drop" Handler="TabItemDrop" />
        </Style>
    </TabControl.Resources>
    <TabControl.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Header}">
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <Label Content="{Binding Body}">
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>


代码隐藏(.xaml.cs):

private void TabItemDrop(object sender, DragEventArgs e)
{
    TabItem tabItem = e.Source as TabItem;
    if(tabItem.Parnent == null){
        //Always null, expect to get the tabControl here
    }
}

FrameworkElement.Parent指向控件的逻辑parent。将 TabControl 的 ItemsSource 属性 绑定到数据 objects 后,TabControl 会生成可视化数据元素的项目容器控件 (TabItem)。在这种情况下,每个容器控件 (TabItem) 都不是 TabControl 的逻辑 child;虽然它是视觉的 child。

为了获得 parent TabControl(在任何情况下),遍历可视化树,例如:

private void TabItemDrop(object sender, DragEventArgs e)
{
    TabItem tabItem = e.Source as TabItem;

    DependencyObject parent = VisualTreeHelper.GetParent(tabItem);

    while (parent != null)
    {
        if (parent is TabControl)
        {
            break;
        }

        parent = VisualTreeHelper.GetParent(parent);
    }

    if (parent != null)
    {
        //Got the tabControl here
    }
}

@Bgorski 正确描述了所有内容。 但我想提供另一种解决方案。 您可以在 XAML 中的标签 属性 中设置绑定(这是后备 属性),然后从此 属性.

中检索值

ElementName 类型绑定示例:

    <TabControl x:Name="tab" ItemsSource="{Binding TabItemList}">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="AllowDrop" Value="True" />
                <EventSetter Event="PreviewMouseMove" Handler="TabItemPreviewMouseMove" />
                <EventSetter Event="Drop" Handler="TabItemDrop" />
                <Setter Property="Tag" Value="{Binding ElementName=tab}"/>
            </Style>
        </TabControl.ItemContainerStyle>

FindAncestor 类型绑定示例:

    <TabControl ItemsSource="{Binding TabItemList}">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="AllowDrop" Value="True" />
                <EventSetter Event="PreviewMouseMove" Handler="TabItemPreviewMouseMove" />
                <EventSetter Event="Drop" Handler="TabItemDrop" />
                <Setter Property="Tag"
                        Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}}"/>
            </Style>
        </TabControl.ItemContainerStyle>

正在检索值:

    private void TabItemDrop(object sender, DragEventArgs e)
    {
        TabItem tabItem = e.Source as TabItem;
        TabControl tab = tabItem.Tag as TabControl;
        if (tab != null)
        {
            //Expect to get the tabControl here
        }
    }