2016-02-11 87 views
0

我有一個使用Devexpress作爲第三方工具的wpf mvvm應用程序。我需要動態創建包含數據網格的選項卡。我想知道什麼是最佳做法。我已經創建的視圖包含一個標籤,並作爲的ContentTemplate所以動態創建WPF MVVM中的TabControl和子網格

  <TabControl ItemsSource="{Binding Workspaces}"> 
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <DataGrid ItemsSource="{Binding Data}" AutoGenerateColumns="False"> 
        <DataGrid.Columns > 
         <DataGridTextColumn Header="Column 1" Binding="{Binding Column1}" /> 
         <DataGridTextColumn Header="Column 2" Binding="{Binding Column2}" /> 
         <DataGridTextColumn Header="Column 3" Binding="{Binding Column3}" /> 
        </DataGrid.Columns> 
       </DataGrid> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 
    </TabControl> 

我的視圖模型

public class DataTest 
{ 
    public string Column1 { get; set; } 
    public string Column2 { get; set; } 
    public string Column3 { get; set; } 
} 


public abstract class WorkspaceViewModel 
{ 
    public String HeaderText { get; set; } 
    public override string ToString() 
    { 
     return HeaderText; 
    } 
    //ObservableCollection 
    public ObservableCollection<DataTest> Data { get; set; } 

} 


public class FirstUserControlViewModel : WorkspaceViewModel 
{ 
    public FirstUserControlViewModel() 
    { 
     base.HeaderText = "My First Tab"; 
     Data = new ObservableCollection<DataTest>(); 
     for (int i = 0; i < 5; i++) 
     { 
      Data.Add(new DataTest() 
         { 
          Column1 = "1st Test" + i.ToString(), 
          Column2 = "1st Test" + i.ToString(), 
          Column3 = "1st Test" + i.ToString() 
         }); 
     } 
    } 
} 


public class SecondUserControlViewModel : WorkspaceViewModel 
{ 
    public SecondUserControlViewModel() 
    { 
     base.HeaderText = "My Second Tab"; 
     Data = new ObservableCollection<DataTest>(); 
     for (int i = 0; i < 5; i++) 
     { 
      Data.Add(new DataTest() 
      { 
       Column1 = "2nd Test" + i.ToString(), 
       Column2 = "2nd Test" + i.ToString(), 
       Column3 = "2nd Test" + i.ToString() 
      }); 
     } 
    } 
} 

public class ThirdUserControlViewModel : WorkspaceViewModel 
{ 
    public ThirdUserControlViewModel() 
    { 
     base.HeaderText = "My Third Tab"; 
     Data = new ObservableCollection<DataTest>(); 
     for (int i = 0; i < 5; i++) 
     { 
      Data.Add(new DataTest() 
      { 
       Column1 = "3rd Test" + i.ToString(), 
       Column2 = "3rd Test" + i.ToString(), 
       Column3 = "3rd Test" + i.ToString() 
      }); 
     } 
    } 
} 

public class ViewModel 
{ 

    private ObservableCollection<WorkspaceViewModel> _workspaces; 

    public ObservableCollection<WorkspaceViewModel> Workspaces 
    { 
     get 
     { 
      if (_workspaces == null) 
      { 
       _workspaces = new ObservableCollection<WorkspaceViewModel>(); 
      } 
      return _workspaces; 
     } 
    } 


    public ViewModel() 
    { 
     Workspaces.Add(new FirstUserControlViewModel()); 
     Workspaces.Add(new SecondUserControlViewModel()); 
     Workspaces.Add(new ThirdUserControlViewModel()); 
    } 

} 

這已經是工作,但我想知道是否有這樣做的更好的方法。我應該把數據網格放在一個用戶控件中,並傳遞其參數Data。我也在這個應用程序中使用Prism有沒有什麼東西可以利用,有一個好處?

回答

0

這將工作,但只有當您的所有選項卡用於顯示完全相同的控件時,網格纔會顯示完全相同的數據結構。

如果你想替代控制或數據,我會建議使用隱含DataTemplates,而不是硬編碼一個ContentTemplate

<TabControl ItemsSource="{Binding Workspaces}"> 
    <TabControl.Resources> 
     <!-- Draw WorkspaceAViewModel with WorkspaceAView --> 
     <DataTemplate TargetType="{x:Type local:WorkspaceAViewModel}"> 
      <local:WorkspaceAView /> 
     </DataTemplate> 

     <!-- Draw WorkspaceBViewModel with WorkspaceBView --> 
     <DataTemplate TargetType="{x:Type local:WorkspaceBViewModel}"> 
      <local:WorkspaceBView /> 
     </DataTemplate> 

     <!-- Draw WorkspaceCViewModel with WorkspaceCView --> 
     <DataTemplate TargetType="{x:Type local:WorkspaceCViewModel}"> 
      <local:WorkspaceCView /> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 

這種方式可以使每個工作區中的任何對象模型(或許還有一個共享的接口,從而有一個將Header文本綁定到的公共屬性),並且可以以任何方式繪製每個選項卡。

public class ViewModel 
{ 
    private ObservableCollection<WorkspaceViewModel> _workspaces; 
    public ObservableCollection<WorkspaceViewModel> Workspaces 
    { 
     get 
     { 
      if (_workspaces == null) 
       _workspaces = new ObservableCollection<WorkspaceViewModel>(); 

      return _workspaces; 
     } 
    } 

    public ViewModel() 
    { 
     Workspaces.Add(new WorkspaceAViewModel()); 
     Workspaces.Add(new WorkspaceBViewModel()); 
     Workspaces.Add(new WorkspaceCViewModel()); 
    } 
} 

public interface IWorkspace 
{ 
    string Header { get; set; } 
} 

public class WorkspaceAViewModel : IWorkspace 
{ 
    // can be anything 
} 

public class WorkspaceBViewModel : IWorkspace 
{ 
    // can be anything 
} 

public class WorkspaceCViewModel : IWorkspace 
{ 
    // can be anything 
}