MVVM用于基于tabcontrol的应用程序

Cod*_*323 1 c# data-binding wpf mvvm

在我的wpf应用程序中,主视图有5个选项卡,有5个不同的用户控件,因为用户控件彼此不相关,我创建了5个不同的视图模型(除了主视图模型).

我想有一个List或字典来获取usercontrols及其viewmodel列表,现在,我想将tabitems与usercontrols列表绑定并分配datacontexts,但由于列表或字典可以更改,我找不到一种将用户控件绑定到tabitems的方法.

例如,如果我有一个标签,它将与我可以分配的用户控件相关联

 tab1View tview=new tab1View();
 tview.DataContext= new tab1ViewModel();
 tab1.Content=tview;
Run Code Online (Sandbox Code Playgroud)

但是,如何从具有usercontrols视图和视图模型的引用的列表中执行相同操作?

请教我一个实现这个目标的最佳方法.

**答案:**

我得到了我需要的答案.首先,应创建视图模型的通用类型集合 C# - 一个列表中的多个泛型类型

public abstract class Metadata
{
}

public class Metadata<DataType> : MetaData where DataType : class
{
private DataType mDataType;
}
List<Metadata> metadataObjects;
metadataObjects.Add(new Metadata<tab1ViewModel>());
metadataObjects.Add(new Metadata<tab2ViewModel>());
Run Code Online (Sandbox Code Playgroud)

如果要使用相同的viewmodel引用多个视图,则创建一个DataTemplate选择器,或者只应用DataTemplate

m-y*_*m-y 5

虽然我会考虑使用框架来帮助您使用MVVM,但有几种方法可以解决这个问题.我自己宣传棱镜.

查看注射


查看发现


DataTemplates - 示例

使用DataTemplates,您在XAML中定义(或在代码中,但更可能是XAML)哪个视图"自动"应用于ContentControl基于视图模型(DataContext)的视图.

XAML资源中的某个位置:

<DataTemplate DataType="{x:Type ViewModel:GeneralSettingsViewModel}">
    <View:GeneralSettingsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:AdvancedSettingsViewModel}">
    <View:AdvancedSettingsView/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

在XAML文件中的某个位置应用了资源:

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

注意:仅当在作用域资源中每个DataTemplate有一个视图模型时,此方法才有效.


DataTemplateSelector

如果您有一个可以应用于多个视图的视图模型,并且您通过其他逻辑确定了这些视图,那么您可能希望使用a DataTemplateSelector.这是一个例子:

XAML资源中的某个位置:

<!-- Possible collision because the DataType is of the same type -->
<DataTemplate x:Key="GeneralSettingsTemplate"
              DataType="{x:Type ViewModel:SettingsViewModel}">
    <View:GeneralSettingsView/>
</DataTemplate>
<DataTemplate x:Key="AdvancedSettingsTemplate"
              DataType="{x:Type ViewModel:SettingsViewModel}">
    <View:AdvancedSettingsView/>
</DataTemplate>
<local:SettingsDataTemplateSelector x:Key="SettingsTemplateSelector"
    GeneralSettingsTemplate="{StaticResource GeneralSettingsTemplate}"
    AdvancedSettingsTemplate="{StaticResource AdvancedSettingsTemplate}" />
Run Code Online (Sandbox Code Playgroud)

在XAML文件中的某个位置应用了资源:

<TabControl ItemsSource="{Binding MyViewModelCollection}"
            ItemTemplateSelector="{StaticResource SettingsTemplateSelector}" />
Run Code Online (Sandbox Code Playgroud)

SettingsTemplateSelector.cs:

public class SettingsDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate GeneralSettingsTemplate { get; set; }
    public DataTemplate AdvancedSettingsTemplate { get; set; }

    public override DataTemplate SelectTemplate(Object item,
        DependencyObject container)
    {
        var vm = item as SettingsViewModel;

        if (vm == null) return base.SelectTemplate(item, container);

        if (vm.IsAdvanced)
        {
            return AdvancedSettingsTemplate;
        }

        return GeneralSettingsTemplate;
    }
}
Run Code Online (Sandbox Code Playgroud)

MSDN:Prism Navigation - http://msdn.microsoft.com/en-us/library/gg430861(v=PandP.40).aspx
这包括Prism Regions以及其他导航部分.

MSND:查看发现与视图注入 - http://msdn.microsoft.com/en-us/library/ff921075(v=pandp.20).aspx
本节介绍了View Discovery和View Injection的区别以及何时使用每个.