如何使用MVVM以编程方式在wpf中添加选项卡项中的控件

Tan*_*nya 4 c# wpf mvvm

我已经创建了一个选项卡控件并动态创建了tabItems,但我不知道如何使用MVVM将控件添加到tabItems中.任何人都可以帮助我

ean*_*son 19

有几种方法可以以编程方式添加Tab项WPF,我将向您展示一个关于如何在我的应用程序中处理此项的简单示例.

首先,我在我的主持人中收集ViewModels了TabItems(或者Workspaces我称之为)的集合MainWindowViewModel.cs:

private ObservableCollection<WorkspaceViewModel> _workspaces;

public ObservableCollection<WorkspaceViewModel> Workspaces
{
    get
    {
        if (_workspaces == null)
        {
            _workspaces = new ObservableCollection<WorkspaceViewModel>();
        }
        return _workspaces;
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,我添加对我的各种控件的引用MainWindow.xaml.这很重要,因为我们希望确保每当集合包含一个ViewModel它显示适合View该模型的集合时.

 <Window.Resources>
        <DataTemplate DataType="{x:Type vm:MyUserControlViewModel}">
            <vw:MyUserControlView/>
        </DataTemplate>
  </Window.Resources>
Run Code Online (Sandbox Code Playgroud)

如果你有多种类型的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>
Run Code Online (Sandbox Code Playgroud)

接下来,我们添加并将其TabControl绑定到我们的WorkspaceCollection.

 <TabControl ItemsSource="{Binding Workspaces}"/>
Run Code Online (Sandbox Code Playgroud)

然后我只是将我添加ViewModels到Collection中,让它们出现在TabControl.

Workspaces.Add(new FirstUserControlViewModel());
Workspaces.Add(new SecondUserControlViewModel());
Workspaces.Add(new ThirdUserControlViewModel());
Run Code Online (Sandbox Code Playgroud)

我的WorkspaceViewModel基础TabItem集合非常简单,看起来像这样:

public abstract class WorkspaceViewModel : BaseViewModel
{
    public String HeaderText { get; set; }
    public override string ToString()
    {
           return HeaderText;
    }
}
Run Code Online (Sandbox Code Playgroud)

添加TabItem:

要创建一个TabItem,你只需要创建一个UserControl和ViewModel你一样正常使用WPF和MVVM模式会.

namespace MyApplication.ViewModel
{
    public class FirstUserControlViewModel : WorkspaceViewModel
    {
        public FirstUserControlViewModel ()
        {
            base.HeaderText = "My First Tab";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,您需要将a绑定View到新的ViewModel.

    <DataTemplate DataType="{x:Type vm:FirstUserControlViewModel }">
        <vw:FirstUserControlView/>
    </DataTemplate>
Run Code Online (Sandbox Code Playgroud)

然后创建一个实例ViewModel并将其添加到您的集合中MainWindowViewModel.

FirstUserControlViewModel firstvm = new FirstUserControlViewModel();
Workspaces.Add(firstvm);
Run Code Online (Sandbox Code Playgroud)

而现在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>
Run Code Online (Sandbox Code Playgroud)

然后我使用MEF将ResourceDictinary暴露给主机,如下所示:

private ResourceDictionary _viewDictionary = new ResourceDictionary();

public ResourceDictionary Dict
{
    get
    {
        return _viewDictionary;
    }
}

_viewDictionary.Source =
                new Uri("/MyExtension.Test;component/View.xaml",
                UriKind.RelativeOrAbsolute);
Run Code Online (Sandbox Code Playgroud)

最后用于Application.Current.Resources.MergedDictionaries.Add将View.xaml加载到主机中.


Ank*_*esh 5

您不必添加控件,只需指定UserControl即可.

TabControl有两个属性ItemTemplate&&Content Template

ItemTemplate用于Tab查看将如何显示的位置

ContentTemplate是Tab内容的外观......所以......

Xaml为上述

            <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> 
Run Code Online (Sandbox Code Playgroud)