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
}
}
我通过绑定创建 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
}
}