繁体   English   中英

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

[英]How to add controls in the tab item programmatically in wpf with MVVM

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

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

首先,我在MainWindowViewModel.csTabItems (或我引用它们的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您只需创建一个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的项目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内容的外观......所以......

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> 

如果你使用mvvm,你不必添加控件。 您只需要为要显示的viewmodel对象创建datatemplate。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM