基于ViewModel类型的TabItem
本文关键字:TabItem 类型 ViewModel 基于 | 更新日期: 2023-09-27 17:50:28
1 -我有TabControl。它的项源是选项卡的集合不同的类型。我需要为每种类型使用不同的XAML。如何形成TabItem标题和内容取决于ViewModel类型?
为每种类型的ViewModel封装XAML的最佳解决方案是什么?我应该为每种类型都设置一个UserControl还是有更好的解决方案?
HumanTabViewModel和InvaderTabViewModel是BaseViewModel类的子类。
<TabControl ItemsSource="{Binding Tabs}">
</TabControl>
class PanelViewModel : BaseViewModel
{
private readonly ObservableCollection<BaseViewModel> _tabs = new ObservableCollection<BaseViewModel>();
public ObservableCollection<BaseViewModel> Tabs
{
get { return _tabs; }
}
private void InitTabs()
{
// Fill Tabs collection with some logic
var tab1 = new HumanTabViewModel ();
_tabs.Add(tab1);
var tab2 = new InvaderTabViewModel ();
_tabs.Add(tab2);
}
}
通过使用datatemplate,您可以为您的类型定义不同的外观:
DataTemplate是用来给逻辑实体(.cs)一个可视化的表示,一旦你把你的逻辑对象(在你的例子中是入侵者/虚拟机)指定为Content,框架将遍历逻辑树,为你的类型寻找一个DataTemplate。
如果没有找到,它将只显示您的类型的"ToString()"。
在您的例子中,您有2个内容TabItem。其中可以通过HeaderTemplate分配一个DataTemplate。
HumanView和InvaderView都是usercontrol。
CS:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items.Add(new HumanViewModel());
Items.Add(new InvaderViewModel());
}
private ObservableCollection<BaseViewModel> items;
public ObservableCollection<BaseViewModel> Items
{
get
{
if (items == null)
items = new ObservableCollection<BaseViewModel>();
return items;
}
}
}
public class BaseViewModel : INotifyPropertyChanged
{
public virtual string Header
{
get { return "BaseViewModel"; }
}
protected void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
public class HumanViewModel : BaseViewModel
{
public override string Header
{
get
{
return "HumanViewModel";
}
}
}
public class InvaderViewModel : BaseViewModel
{
public override string Header
{
get
{
return "InvaderViewModel";
}
}
}
XAML: <Window>
<Window.Resources>
<DataTemplate DataType="{x:Type local:HumanViewModel}">
<local:HumanView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:InvaderViewModel}">
<local:InvaderView />
</DataTemplate>
<Style TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Header,Mode=OneWay}" FontSize="18" FontWeight="Bold" Foreground="DarkBlue" Width="Auto"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl ItemsSource="{Binding Items, Mode=OneWay}" />
</Grid>
</Window>