我有一个TabControl,它有一个特殊的“+ tab”,定义如下:
<TabControl x:Name="ProjectsTabControl">
<local:ProjectTabItem x:Name="AddProjectTabTabItem" Header="+" MouseUp="AddProjectButton_Click" PreviewMouseDown="AddProjectTabTabItem_PreviewMouseDown"/>
</TabControl>
“MouseDown”只是将鼠标事件参数标记为已处理(为了防止+选项卡被选中)。“Button_Click”添加具有以下样式的新选项卡:
<Window.Resources>
<Style x:Key="CloseableTabItemStyle" TargetType="local:ProjectTabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<DockPanel>
<TextBlock Text="{Binding}" Margin="0,0,5,0"/>
<Button Content="X" Click="CloseButton_Click" Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:ProjectTabItem}}}"/>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
这些是我使用的“实际”选项卡。每个这样的标签在其标题中都有一个“关闭按钮”。正如您所看到的,关闭按钮的标记被设置为ProjectTabItem祖先。
我的CloseButton逻辑如下:
private async void CloseButton_Click(object sender, RoutedEventArgs e)
{
if (sender is Button closeButton && closeButton.Tag is ProjectTabItem tabItem)
{
ProjectsTabControl.Items.Remove(tabItem);
if (ProjectsTabControl.SelectedIndex == ProjectsTabControl.Items.Count - 1)
{
ProjectsTabControl.SelectedIndex--;
}
}
}
这里的想法是防止+选项卡被选中(然而,即使我选择了+选项卡,我很快就会描述的问题也会发生)。
当我关闭最后一个选项卡(即+选项卡之前的最后一个选项卡)时,我看到以下错误
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.TabControl', AncestorLevel='1''. BindingExpression:Path=TabStripPlacement; DataItem=null; target element is 'ProjectTabItem' (Name=''); target property is 'NoTarget' (type 'Object')
只有在关闭标签时选择标签时才会发生这种情况。
看起来如果我在关闭“最后一个”标签之前抢先打开一个新标签,这个问题就不会发生。(然而,这对我没有帮助,因为我想允许除了+选项卡之外根本没有选项卡。
这是什么原因造成的?我该怎么修复它?
编辑:我已经找到了一个,我猜,解决办法here。在删除选项卡之前设置tabItem.Template = null;
实际上解决了这个问题。所以让我把我的问题改成:为何会出现这种情况呢?这个“解决方案”实际上是一个解决方案,还是它只是抑制了我代码中的一些潜在的重要问题?
1条答案
按热度按时间plicqrtu1#
只要你使用代码隐藏,你就永远不会从WPF中得到乐趣。你总是会踩到“变通方案陷阱”。如果你遵循MVVM模式,事情会变得容易得多。
我刚刚在我的应用程序中创建了一个TabControl,它绑定到Observable Collection
在这个Observable Collection中有TabItemModels:
这里的XAML -此TabControl的一部分:
MainViewModel中的声明:
XAML中的按钮触发TabItemModel中的Relay-Command,它向View-Model发送消息以关闭选项卡。我只是从集合中删除了这个特定的模型:
对我来说很好。