Есть несколько способов программно добавить элементы табуляции в WPF
, и я собираюсь показать вам простой пример того, как я справляюсь с этим в моем приложении.
Сначала я размещаю коллекцию ViewModels
для TabItems
(или Workspaces
, как я их называю) в моем MainWindowViewModel.cs
:
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>
Если у вас есть несколько типов пользовательских элементов управления, вы просто добавляете их все вот так:
<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
коллекцией.
<TabControl ItemsSource="{Binding Workspaces}"/>
Затем я просто добавляю свои ViewModels
в коллекцию, чтобы они отображались в TabControl
.
Workspaces.Add(new FirstUserControlViewModel());
Workspaces.Add(new SecondUserControlViewModel());
Workspaces.Add(new ThirdUserControlViewModel());
Мой WorkspaceViewModel
, на котором я основываю коллекцию TabItem
, очень прост и выглядит примерно так:
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
проектов. У меня есть сообщение здесь , с некоторыми дополнительными деталями.
Все, что вам нужно сделать, это добавить 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>
Затем я открываю ResourceDictinary с помощью MEF для хоста следующим образом:
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 в хост.