2011-11-07 81 views
1

在我的wpf应用程序中,主视图有5个不同的用户控件,因为用户控件不相互关联,所以我创建了5个不同的视图模型(除了主视图模型)。MVVM基于tabcontrol的应用程序

我想有一个列表或字典有usercontrols及其视图模型列表, 现在,我想绑定tabitems与usercontrols列表并分配datacontexts,但由于列表或字典可以是改变了,我没有找到一种方法来绑定usercontrols到tabitems。

例如,如果我有这将与用户控件相关联一个制表我可以分配

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

但我怎么可以这样做从具有视图和的ViewModels的参考名单usercontrols?

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

**答:**

我得到了我所需要的答案。视图模型的 首先,泛型类型集合应创建 C# - Multiple generic types in one list

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>()); 

然后,如果多个视图均与同一视图模型引用或只是应用的DataTemplate

+0

除非'DataObject'为您的代码的其余部分提供了一个有用的接口,否则我建议只编写一个'object'列表。您的视图仍然可以绑定到它,并且您不必从不提供封装优势的其他类中衍生出来,并且使代码混乱。 –

+0

使用ObservableCollection而不是List。 –

+0

@ m-y:如果列表没有改变,那么列表不是一个错误的选择。 –

回答

5

有几种方法可以解决这个问题,但我会考虑使用框架来帮助您使用MVVM。我自己推动Prism

View Injection


View Discovery


的DataTemplates - Sample

随着你在XAML中定义的DataTemplates(或代码,BU t XAML更有可能)基于视图模型(DataContext)将“自动”应用于ContentControl的视图。

某处在XAML资源:

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

某处在XAML文件中已应用到它的资源:如果你有每一个视图模型这仅适用于:

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

注范围资源中的DataTemplate。


DataTemplateSelector

如果你有一个可以应用到多个视图的视图模型,你确定通过附加逻辑的观点,你会想用一个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}" /> 

某处在XAML文件具有施加给它的资源:

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

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:棱镜导航 - http://msdn.microsoft.com/en-us/library/gg430861(v=PandP.40).aspx
这包括棱镜区域以及导航的其他部分。

MSND:查看发现vs查看注入 - http://msdn.microsoft.com/en-us/library/ff921075(v=pandp.20).aspx
本节介绍View Discovery和View Injection的不同之处以及何时使用它们。

+0

谢谢....我会试试这种方式 – Coder323

+0

嗨,我实现你的例子,它的工作非常好:)谢谢 – Coder323

+0

哪个实现? –

2

创建创建一个DataTemplate选择您绑定到选项卡控件的ItemsSource的视图模型集合。然后创建一个DataTemplateSelector为每个视图模型选择一个视图。

+0

我也会试试 – Coder323

+1

'DataTemplateSelector'是不必要的。如果你有一个可以应用于多个视图的视图模型,那么你只需要这个,在这种情况下,你需要额外的逻辑来确定**要返回哪个** DataTemplate,否则会导致冲突。查看我的答案的更新,显示此示例。 –