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

时间:2012-01-06 09:00:14

标签: c# wpf mvvm

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

3 个答案:

答案 0 :(得分:19)

有几种方法可以在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>

如果你有多种类型的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集合。

 <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,您只需创建一个UserControlViewModel,就像通常使用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。在这些情况下,您需要让插件在应用程序域中注册ViewViewModel

这很容易做到,实际上我为我的一个基于MEF的项目做了些什么。我有一篇帖子here,还有其他一些细节。

您需要做的就是在插件/扩展程序中添加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加载到主机中。

答案 1 :(得分:5)

您不必添加您只需指定UserControl的控件。

TabControl有两个属性ItemTemplate&amp;&amp; Content Template

ItemTemplate用于Tab将如何看作

ContentTemplate是标签内容的外观......所以......

以上

的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> 

答案 2 :(得分:1)

如果使用mvvm,则无需添加控件。您只需要为要显示的viewmodel对象创建数据窗口。

您只需要一个与您的viewmodel绑定的contentcontrol / presenter,datatemplate将显示您想要的内容。