2014-06-24 33 views
0

我有一個DXTabControl。 DXTabItems是通過我的ViewModel生成的。DevExpress - MVVM - 用不同的ViewModel生成TabItems

// MainViewModel

public MainViewModel() 
{ 
    var items = new ObservableCollection<DXTabItem>(); 
    items.Add(
     new DXTabItem() 
     { 
      Header = "Test1", 
      Content = new WebViewModel() 
     }); 

    items.Add(
     new DXTabItem() 
     { 
      Header = "Test2", 
      Content = new CMSViewModel() 
     }); 

    TabItems = items; 
} 

private ObservableCollection<DXTabItem> _tabItems; 
public ObservableCollection<DXTabItem> TabItems 
{ 
    get { return _tabItems; } 
    set { SetProperty(ref _tabItems, value,() => TabItems); } 
} 

我有一個DataTemplate的工作和我的TabItem仍然沒有表現出任何用戶控件。

//MainView.xaml

<DataTemplate x:Key="WebTemplate" DataType="{x:Type viewmodel:WebViewModel}"> 
    <view:WebView/> 
</DataTemplate> 

<DataTemplate x:Key="CMSTemplate" DataType="{x:Type viewmodel:CMSViewModel}"> 
    <view:CMSView/> 
</DataTemplate> 

<datatemplate:TemplateSelector x:Key="DataTemplateSelector" 
         WebTemplate="{StaticResource WebTemplate}" 
         CMSTemplate="{StaticResource CMSTemplate}" /> 

<dx:DXTabControl ItemsSource="{Binding TabItems}" ItemTemplateSelector="{StaticResource DataTemplateSelector}" /> 

// DataTemplateSelector

public class TemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate WebTemplate { get; set; } 
    public DataTemplate CMSTemplate { get; set; } 

    public override DataTemplate SelectTemplate(Object item, 
     DependencyObject container) 
    { 

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

     if (item.GetType() == typeof(WebViewModel)) 
     { 
      return WebTemplate; 
     } 

     else if (item.GetType() == typeof(CMSViewModel)) 
     { 
      return CMSTemplate; 
     } 

     else return base.SelectTemplate(item, container); 

    } 
} 

一切工作,除了展示我所需要的內容。沒有顯示視圖。任何想法?我錯過了什麼?

+0

你有沒有得到這個答案?我今天遇到了與DevExpress v14.1相同的問題。 – Ray

+0

嗯,是的,有些人。我正在與caliburn.micro合作,你呢?當我明天在辦公室時,我可以試着爲你提供答案。目前,我正在使用智能手機。 – Insight

+0

我試圖弄清楚如何讓一個用戶控件出現在一個標籤項(不是標題,而是在內容區)。不能與caliburn.micro一起工作。 – Ray

回答

0

以下回答基於caliburn.micro。

第1步:公約添加到引導程序

public Bootstrapper() 
{ 
ConventionManager.AddElementConvention<DXTabControl>(DXTabControl.ItemsSourceProperty, "ItemsSource", "DataContextChanged") 
      .ApplyBinding = (viewModelType, path, property, element, convention) => 
     { 
      if (!ConventionManager.SetBindingWithoutBindingOrValueOverwrite(viewModelType, path, property, element, convention, DXTabControl.ItemsSourceProperty)) 
      { 
       return false; 
      } 
      var tabControl = (DXTabControl)element; 
      if (tabControl.ItemTemplate == null && tabControl.ItemTemplateSelector == null && property.PropertyType.IsGenericType) 
      { 
       var itemType = property.PropertyType.GetGenericArguments().First(); 
       if (!itemType.IsValueType && !typeof(string).IsAssignableFrom(itemType)) 
       { 
        tabControl.ItemTemplate = ConventionManager.DefaultItemTemplate; 
       } 
      } 

      ConventionManager.ConfigureSelectedItem(element, Selector.SelectedItemProperty, viewModelType, path); 

      if (string.IsNullOrEmpty(tabControl.DisplayMemberPath)) 
      { 
       ConventionManager.ApplyHeaderTemplate(tabControl, DXTabControl.ItemHeaderTemplateProperty, DXTabControl.ItemHeaderTemplateSelectorProperty, viewModelType); 
      } 
      return true; 
     }; 

[...] 
} 

現在你可以在任何屏幕收集綁定到你的DXTabControl。

第2步:在視圖模型創建集合

public class MainViewModel : Screen 
{ 
    public MainViewModel() 
    { 
     DisplayName = "DevExpress Test Environment"; 
    } 


    private static BindableCollection<Screen> _tbCtrl = new BindableCollection<Screen>(); 
    public BindableCollection<Screen> TbCtrl 
    { 
     get { return _tbCtrl; } 
     set 
     { 
      _tbCtrl = value; 
      NotifyOfPropertyChange(() => TbCtrl); 
     } 
    } 
} 

你可以如將任何其他基於Screen類的ViewModel放入您的集合中。這意味着,您將能夠顯示每個tabitem的內容。

3步:創建(XAML代碼)的DXTabControl在查看

<dx:DXTabControl x:Name="TbCtrl" /> 

搏一搏。打開反饋。

沒有Caliburn.Micro

///替代解決方案

步驟1:將DXTabControl添加到您的MainView(XAML代碼)

<dx:DXTabControl ItemsSource="{Binding TbCtrlItems}" /> 

第2步:您MainViewModel需要添加這些項目像我上面已經描述了(我的問題),但在這種情況下,你必須指定內容屬性

public MainViewModel() 
    { 
     _tbCtrlItems.Add(new DXTabItem() 
     { 
      Header = "Test1", 
      Content = new Views.View1() {DataContext = new ViewModel1()} 
     }); 

     _tbCtrlItems.Add(new DXTabItem() 
     { 
      Header = "Test2", 
      Content = new Views.View2() { DataContext = new ViewModel2() } 
     }); 


    } 

    private ObservableCollection<DXTabItem> _tbCtrlItems = new ObservableCollection<DXTabItem>(); 

    public ObservableCollection<DXTabItem> TbCtrlItems 
    { 
     get { return _tbCtrlItems; } 
     set { SetProperty(ref _tbCtrlItems, value,() => TbCtrlItems); } 
    } 

我希望這個答案是有幫助的。