2011-11-07 79 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,否則會導致衝突。查看我的答案的更新,顯示此示例。 –