[英]How to add tab controls dynamically in WPF MVVM when one or more tabs already existed in design
[英]How to add controls in the tab item programmatically in wpf with MVVM
我已经创建了一个选项卡控件并动态创建了tabItems,但我不知道如何使用MVVM将控件添加到tabItems中。 任何人都可以帮助我
有几种方法可以在WPF
以编程方式添加Tab项,我将向您展示一个关于如何在我的应用程序中处理此项的简单示例。
首先,我在MainWindowViewModel.cs
为TabItems
(或我引用它们的Workspaces
)托管ViewModels
的集合:
private ObservableCollection<WorkspaceViewModel> _workspaces;
public ObservableCollection<WorkspaceViewModel> Workspaces
{
get
{
if (_workspaces == null)
{
_workspaces = new ObservableCollection<WorkspaceViewModel>();
}
return _workspaces;
}
}
接下来,我在MainWindow.xaml
添加对各种控件的引用。 这很重要,因为我们希望确保只要集合包含ViewModel
,它就会显示该模型的相应View
。
<Window.Resources>
<DataTemplate DataType="{x:Type vm:MyUserControlViewModel}">
<vw:MyUserControlView/>
</DataTemplate>
</Window.Resources>
如果你有多种类型的UserControls,你只需在这里添加它们,如下所示:
<Window.Resources>
<DataTemplate DataType="{x:Type vm:FirstUserControlViewModel}">
<vw:FirstUserControlView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SecondUserControlViewModel}">
<vw:SecondUserControlView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ThirdUserControlViewModel}">
<vw:ThirdUserControlView/>
</DataTemplate>
</Window.Resources>
接下来,我们添加TabControl
并将其绑定到我们的Workspace
Collection。
<TabControl ItemsSource="{Binding Workspaces}"/>
然后我只需将我的ViewModels
添加到Collection中,让它们显示在TabControl
。
Workspaces.Add(new FirstUserControlViewModel());
Workspaces.Add(new SecondUserControlViewModel());
Workspaces.Add(new ThirdUserControlViewModel());
我基于TabItem
集合的WorkspaceViewModel
非常简单,看起来像这样:
public abstract class WorkspaceViewModel : BaseViewModel
{
public String HeaderText { get; set; }
public override string ToString()
{
return HeaderText;
}
}
添加TabItem:
要创建一个TabItem
您只需创建一个UserControl
和ViewModel
就像您通常使用WPF和MVVM模式一样。
namespace MyApplication.ViewModel
{
public class FirstUserControlViewModel : WorkspaceViewModel
{
public FirstUserControlViewModel ()
{
base.HeaderText = "My First Tab";
}
}
}
接下来,您需要将View
绑定到新的ViewModel
。
<DataTemplate DataType="{x:Type vm:FirstUserControlViewModel }">
<vw:FirstUserControlView/>
</DataTemplate>
然后创建ViewModel
的实例并将其添加到MainWindowViewModel
的集合。
FirstUserControlViewModel firstvm = new FirstUserControlViewModel();
Workspaces.Add(firstvm);
现在TabItem
应该显示在TabControl
。
使用扩展动态加载TabItems:
在某些情况下,甚至可能需要加载TabItems
从插件动态无主机应用程序第一次知道有关TabItem
。 在这些情况下,您需要让插件将View
和ViewModel
注册到应用程序域。
这很容易做到,实际上我为我的一个基于MEF
的项目MEF
。 我在这里有一个帖子,还有一些额外的细节。
您需要做的就是在插件/扩展中添加Resource Dictionary
,并确保在导入插件后宿主应用程序加载它。
为了向您展示一个快速示例,我将在扩展中使用View.xaml
:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vw="clr-namespace:MyExtension.Test">
<DataTemplate DataType="{x:Type vw:TestViewModel}">
<vw:TestView/>
</DataTemplate>
</ResourceDictionary>
然后我使用MEF将ResourceDictinary暴露给主机,如下所示:
private ResourceDictionary _viewDictionary = new ResourceDictionary();
public ResourceDictionary Dict
{
get
{
return _viewDictionary;
}
}
_viewDictionary.Source =
new Uri("/MyExtension.Test;component/View.xaml",
UriKind.RelativeOrAbsolute);
最后,您使用Application.Current.Resources.MergedDictionaries.Add
将View.xaml加载到主机中。
您不必添加控件,只需指定UserControl即可。
TabControl有两个属性ItemTemplate
&& Content Template
ItemTemplate用于Tab
外观
ContentTemplate是Tab内容的外观......所以......
<TabControl Grid.Row="1"
ItemsSource="{Binding Path=TabList}"
SelectedItem="{Binding Path=SelectedTab,
Mode=TwoWay}"
<!--This is How tab will look--> >
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="20"
Height="20"
Margin="0,0,2,0"
Source="Images\TreeView\yourFavImg.png" />
<TextBlock Margin="0,4,0,0"
VerticalAlignment="Center"
FontWeight="Bold"
Text="{Binding Path=TabText}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<!--This will be the content for the tab control-->
<TabControl.ContentTemplate>
<DataTemplate>
<!--This User Control will contain the controls you like-->
<ViewLayer:YourFavUserControl />
</DataTemplate>
</TabControl.ContentTemplate>
如果你使用mvvm,你不必添加控件。 您只需要为要显示的viewmodel对象创建datatemplate。
您只需要一个与您的viewmodel绑定的contentcontrol / presenter,datatemplate将显示您想要的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.