我有一个包含TabControl的Usercontrol(TabUserControl)。该UserControl的Viewmodel加载TabItems的Observable集合。这些项目中的一个是另一个用户控件。当我只是在tabcontrol中加载文本时,没有问题,但我如何将其他用户控件加载到TabUserControl的tabitem中。我正在使用MVVM。
这是我的代码:
public class TabItem
{
public string Header { get; set; }
public object Content { get; set; } // object to allow all sort of items??
}
TabUserControl 的视图模型
public class TabViewModel
{
public ObservableCollection<TabItem> Tabs {get;set;}
public TabViewModel()
{
Tabs = new ObservableCollection<TabItem>();
//Tabs.Add(new TabItem { Header = "Overview", Content = new OverviewViewModel() }); How to load a usercontrol here if it's in the ItemCollection?
Tabs.Add(new TabItem { Header = "Overview", Content = "Bla bla bla" });
Tabs.Add(new TabItem { Header = "Two", Content = "Two's content" });
}
}
然后是TabControl XAML:
<TabControl x:Name="_tabControl"
ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header"
Value="{Binding Header}" />
<Setter Property="Content"
Value="{Binding Content}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
只要我不在tabItems集合中加载用户控件的视图模型,它就可以工作。如何将UserTabControl加载到TabItem?其目的是每个选项卡项都将包含一个用户控件。然后,每个用户控件都做自己的事情。
希望有人能帮助我,因为我是一个WPF初学者。Thx!
理想情况下,TabControl.ItemsSource
应设置为ViewModels
的集合,DataTemplates
应用于告诉WPF用特定的UserControl
绘制每个ViewModel
。
这使您的业务逻辑(ViewModels
)与UI(Views
)完全分离
例如,
<TabControl x:Name="MyTabControl"
ItemsSource="{Binding TabViewModels}"
SelectedItem="{Binding SelectedTabViewModel}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type my:ViewModelA}">
<my:ViewAUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type my:ViewModelB}">
<my:ViewBUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type my:ViewModelC}">
<my:ViewCUserControl />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
包含TabControl的DataContext:的ViewModel
TabViewModels = new ObservableCollection<ITabViewModel>();
TabViewModels.Add(new ViewModelA { Header = "Tab A" });
TabViewModels.Add(new ViewModelB { Header = "Tab B" });
TabViewModels.Add(new ViewModelC { Header = "Tab C" });
SelectedTabViewModel = TabViewModels[0];
感谢Rachel的回答。但它强制在编译时本身声明DataContext。像您所做的那样,在TabControl的DataTemplate中将每个视图关联到它们各自的ViewModel。当我们把它移到ViewModel时,我们可以实现动态的ViewModel链接。方法如下:
XAML:
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="Content" Value="{Binding Content}" />
</Style>
</TabControl.ItemContainerStyle>
VM:
public ObservableCollection<TabItem> TabItems { get; set; }
public MainWindowViewModel()
{
TabItems = new ObservableCollection<TabItem>
{
new TabItem{Content = new TabAView() {DataContext = new TabAViewModel()}, Header = "Tab A"},
new TabItem{Content = new TabBView(), Header = "Tab B"}
};
}
我们甚至可以使用Action委托来延迟并仅在选项卡SelectionChangedEvent时调用TabItems的初始化。如果UserControl视图具有许多UI元素,则可以节省大量内存。