C# 添加到绑定TabControl(mvvm)后获取新选项卡的父级
我正在使用以下指南向选项卡添加关闭按钮: 这已成为一个问题,因为事件使用添加选项卡的“父级”从tabcontrol中删除该选项卡。我正在使用mvvm绑定tab控件,因此显然没有设置parent属性,并且当事件试图从中删除时,为父属性提供了null引用异常 这是装订,这样你就知道了:C# 添加到绑定TabControl(mvvm)后获取新选项卡的父级,c#,wpf,mvvm,tabcontrol,C#,Wpf,Mvvm,Tabcontrol,我正在使用以下指南向选项卡添加关闭按钮: 这已成为一个问题,因为事件使用添加选项卡的“父级”从tabcontrol中删除该选项卡。我正在使用mvvm绑定tab控件,因此显然没有设置parent属性,并且当事件试图从中删除时,为父属性提供了null引用异常 这是装订,这样你就知道了: <TabControl Name="tabControl" Margin="0,22,0.2,-5.2" ItemsSource="{Binding Tabs}" Background="#FF4C76B2"
<TabControl Name="tabControl" Margin="0,22,0.2,-5.2" ItemsSource="{Binding Tabs}" Background="#FF4C76B2"/>
以下是发生空引用的事件:
void button_close_Click(object sender, RoutedEventArgs e)
{
((TabControl)this.Parent).Items.Remove(this);
}
在我看来,有两种选择:
- 尝试找到另一种方法来删除选项卡(不带父项) 财产)
- 尝试找到一种方法以某种方式设置父属性(不能 如果直接执行,则会引发编译器错误)
- 我觉得这听起来不像是MVVM。我们处理的是数据,而不是UI元素。我们使用的类集合包含满足某些要求所需的所有属性,数据将这些属性绑定到
DataTemplate
s中的UI控件。通过这种方式,我们通过向这些集合中添加数据项来添加UI控件,并让出色的WPF模板系统来处理UI
例如,您有一个TabControl
,我们想从中添加或删除TabItem
s。。。以适当的MVVM方式。首先,我们需要一组可以表示每个TabItem
的项:
public static DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<string>), typeof(TestView));
public ObservableCollection<string> Items
{
get { return (ObservableCollection<string>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
我们将集合数据绑定到TabControl.ItemsSource
属性,并将TabControl.ItemTemplate
设置为名为ItemTemplate
的资源。现在我们来看一下:
xmlns:System="clr-namespace:System;assembly=mscorlib"
...
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type System:String}">
<TabItem Header="{Binding}" />
</DataTemplate>
注意,为了完整起见,我包含了System
XML名称空间前缀,但您不需要它,因为DataType
将是您自己的自定义类。您还需要更多的DataTemplate
s。例如,如果您的自定义类有一个标题
属性和一个内容
属性,这是另一个自定义类,我们称之为内容
,它包含选项卡项.Content
属性的所有属性,您可以执行以下操作:
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type YourPrefix:YourClass}">
<TabItem Header="{Binding Header}" Content="{Binding Content}" />
</DataTemplate>
<DataTemplate DataType="{x:Type YourPrefix:Content}">
<YourPrefix:SomeUserControl DataContext="{Binding}" />
</DataTemplate>
因此,无论哪个视图模型有选项卡
集合,都应该有一个AddTabCommand
和一个CloseTabCommand
,用于在选项卡
集合中添加和删除项。但是,为了让它正常工作,您的ClosableTab
类应该是一个数据类,而不是一个UI控件类。如果是UI控件,请使用DataTemplate
指定它
您可以从MSDN上找到有关RelayCommand
的信息。我绑定itemsSource的可观察集合是上面代码中的“选项卡”。至于只是从集合中删除,是的,这就是我最终要做的(尽管我不喜欢这样,我必须传递viewmodel的引用才能从中获取Tabs属性)
xmlns:System="clr-namespace:System;assembly=mscorlib"
...
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type System:String}">
<TabItem Header="{Binding}" />
</DataTemplate>
Items.Add("Tab 1");
Items.Add("Tab 2");
Items.Add("Tab 3");
<DataTemplate x:Key="ItemTemplate" DataType="{x:Type YourPrefix:YourClass}">
<TabItem Header="{Binding Header}" Content="{Binding Content}" />
</DataTemplate>
<DataTemplate DataType="{x:Type YourPrefix:Content}">
<YourPrefix:SomeUserControl DataContext="{Binding}" />
</DataTemplate>
<Button Content="Close Tab" Command="{Binding CloseTabCommand}"
CommandParameter="{Binding}" />
...
public ICommand CloseTabCommand
{
get { return new ActionCommand(action => Items.Remove(action),
canExecute => canExecute != null && Items.Contains(canExecute)); }
}