简体   繁体   English

MVVM用于基于TabControl的应用程序

[英]MVVM for tabcontrol based application

In my wpf application the main view has 5 tabs with 5 different usercontrols , since the user controls are not related to each other, I have created 5 different view models (apart from the main viewmodel). 在我的wpf应用程序中,主视图具有5个带有5个不同用户控件的选项卡,由于用户控件彼此之间不相关,因此我创建了5个不同的视图模型(除主视图模型之外)。

I thought of having a List or dictionary to have the list of usercontrols and its viewmodels, Now, I would like to bind the tabitems with the list of usercontrols and assign the datacontexts, but since the list or dictionary can be changed, I dont find a way to bind the usercontrols to the tabitems. 我想到要有一个列表或字典来包含用户控件及其视图模型的列表,现在,我想将Tabitems与用户控件的列表绑定并分配数据上下文,但是由于列表或字典可以更改,所以我找不到一种将用户控件绑定到列表项的方法。

For example, If I have a single tab which will be associated with a usercontrol I can assign 例如,如果我有一个与用户控件相关联的标签,则可以分配

 tab1View tview=new tab1View();
 tview.DataContext= new tab1ViewModel();
 tab1.Content=tview;

But how can I do the same from a list which has the reference of the view and viewmodels of the usercontrols? 但是,如何从具有对用户控件的视图和视图模型的引用的列表中进行操作呢?

Please teach me a best way to achieve this. 请教我实现此目标的最佳方法。

**Answer: ** **答案:**

I got the answer for what I need. 我得到了我需要的答案。 First, Generic type collection of the view models should be created C# - Multiple generic types in one list 首先,应创建视图模型的泛型类型集合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>());

Then create a DataTemplate selector if multiple views are to be be referenced with same viewmodel or just apply the DataTemplate 如果要使用同一viewmodel引用多个视图,则创建一个DataTemplate选择器,或者仅应用DataTemplate

There are a few ways to handle this, though I'd look at using frameworks to help you with MVVM. 有几种方法可以解决此问题,尽管我将研究使用框架来帮助您使用MVVM。 I myself promote Prism . 我本人提倡棱镜

View Injection 查看注射


View Discovery 查看发现


DataTemplates - Sample DataTemplates- 示例

With DataTemplates you're defining in XAML (or in code, but XAML is more likely) which view to "automagically" apply to a ContentControl based upon the view-model (DataContext). 使用DataTemplates,您可以在XAML(或代码中,但是XAML可能性更高)中定义,哪些“自动”视图基于视图模型(DataContext)应用于ContentControl

Somewhere in the XAML resources: XAML资源中的某个位置:

<DataTemplate DataType="{x:Type ViewModel:GeneralSettingsViewModel}">
    <View:GeneralSettingsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModel:AdvancedSettingsViewModel}">
    <View:AdvancedSettingsView/>
</DataTemplate>

Somewhere in the XAML file that has the resources applied to it: XAML文件中已对其应用了资源的某个位置:

 <TabControl ItemsSource="{Binding MyViewModelCollection}" />

Note: This only works if you have one view-model per DataTemplate in the scoped resource. 注意:仅当在范围资源中每个DataTemplate具有一个视图模型时,此方法才有效。


DataTemplateSelector DataTemplateSelector

If you have a view-model that can be applied to multiple views and you determine those views through additional logic, you would want to use a DataTemplateSelector . 如果您有一个可以应用于多个视图的视图模型,并且通过其他逻辑确定了这些视图,则需要使用DataTemplateSelector Here is an example: 这是一个例子:

Somewhere in the XAML resources: 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}" />

Somewhere in the XAML file that has the resources applied to it: XAML文件中已对其应用了资源的某个位置:

<TabControl ItemsSource="{Binding MyViewModelCollection}"
            ItemTemplateSelector="{StaticResource SettingsTemplateSelector}" />

SettingsTemplateSelector.cs: 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;
    }
}

MSDN: Prism Navigation - http://msdn.microsoft.com/en-us/library/gg430861(v=PandP.40).aspx MSDN:棱镜导航-http: //msdn.microsoft.com/zh-cn/library/gg430861( v=PandP.40) .aspx
This covers Prism Regions as well as other parts of navigation. 这涵盖了棱柱区域以及导航的其他部分。

MSND: View Discovery vs View Injection - http://msdn.microsoft.com/en-us/library/ff921075(v=pandp.20).aspx MSND:视图发现与视图注入-http: //msdn.microsoft.com/zh-cn/library/ff921075( v=pandp.20) .aspx
This section covers the differences of View Discovery and View Injection and when to use each. 本节介绍了View Discovery和View Injection的区别以及何时使用它们。

Create a collection of your viewmodels that you bind to the ItemsSource of the tab control. 创建绑定到选项卡控件的ItemsSource的视图模型的集合。 Then create a DataTemplateSelector to select a view for each viewmodel. 然后创建一个DataTemplateSelector来为每个视图模型选择一个视图。

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

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