2010-11-04 24 views
9

我有3個共享相同數據類型的數據網格。我想配置一次列綁定並讓3個數據網格共享資源。我可以在DataGrid表格中共享DataGrid.Columns

例如

 <DataGrid Grid.Row="1" x:Name="primaryDG" ItemsSource="{Binding Path=dgSource AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/> 
     </DataGrid.Columns> 
    </DataGrid> 

有沒有一種方法來設置的ItemsSource爲每個數據網格,然後用一個DataTemplate或控件模板來獲取列?

+1

類似的問題,有用的答案:http://stackoverflow.com/questions/5716123/wpf-datagrid-columns-in-style-or-resource – surfen 2011-12-02 12:20:24

回答

4

是......兩種方式。一,你可以簡單地添加一個樣式DataGrid,設置這樣的列...

<Style x:Key="MyColumnDefsStyle" x:Shared="True" TargetType="DataGrid"> 
    <Setter Property="Columns"> 
     <Setter.Value> 
      <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/> 
      <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/> 
     </Setter.Value> 
    </Setter> 
</Style> 

<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo1}" /> 
<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo2}" /> 
<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo3}" /> 

這一工程,但表示,如果你把它應用到自己可能已被使用的風格多個網格的一個問題。

在這種情況下,另一種更靈活的方式效果更好。然而,這需要創建一個XAML友好的類來表示ObservableCollection<DataGridColumn>(儘管您在技術上只說列,我喜歡自己完成,所以我也會爲行做一個)然後將它們添加到您可以在XAML中引用的位置命名空間。 (我把我的xmlns:dge爲「DataGridEnhancements」),那麼您可以使用它像這樣:

在代碼somwhere(我會讓它訪問應用範圍)...

public class DataGridRowsCollection : ObservableCollection<DataGridRow>{} 
public class DataGridColumnsCollection : ObservableCollection<DataGridColumn>{} 

然後在資源...

<dge:DataGridColumnsCollection x:Key="MyColumnDefs" x:Shared="True"> 
    <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/> 
    <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/> 
    <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/> 
    <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/> 
</dge:DataGridColumnsCollection> 

終於在XAML ...

<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo1}" /> 
<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo2}" /> 
<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo3}" /> 

HTH,

馬克

編輯: 既然你不能設置DataGrid.Columns屬性,則需要增強DataGridView(如在評論中提到的)。下面是一個EnhancedDataGrid代碼:

public class EnhancedDataGrid : DataGrid 
    { 
     //the dependency property for 'setting' our columns 
     public static DependencyProperty SetColumnsProperty = DependencyProperty.Register(
      "SetColumns", 
      typeof (ObservableCollection<DataGridColumn>), 
      typeof (EnhancedDataGrid), 
      new FrameworkPropertyMetadata 
      { 
       DefaultValue = new ObservableCollection<DataGridColumn>(), 
       PropertyChangedCallback = EnhancedDataGrid.SetColumnsChanged, 
       AffectsRender = true, 
       AffectsMeasure = true, 
       AffectsParentMeasure = true, 
       IsAnimationProhibited = true, 
       DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, 
      }); 

     //callback to reset the columns when our dependency property changes 
     private static void SetColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var datagrid = (DataGrid) d; 

      datagrid.Columns.Clear(); 
      foreach (var column in (ObservableCollection<DataGridColumn>)e.NewValue) 
      { 
       datagrid.Columns.Add(column); 
      } 
     } 

     //The dependency property wrapper (so that you can consume it inside your xaml) 
     public ObservableCollection<DataGridColumn> SetColumns 
     { 
      get { return (ObservableCollection<DataGridColumn>) this.GetValue(EnhancedDataGrid.SetColumnsProperty); } 
      set { this.SetValue(EnhancedDataGrid.SetColumnsProperty, value); } 
     } 
    } 

現在你可以設置與SetColumns列依賴於你的CustomControl創建屬性:

<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo1}" /> 
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo2}" /> 
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo3}" /> 
+1

它真的有用嗎? Columns屬性沒有設置:http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.columns.aspx – surfen 2011-12-02 12:18:32

+2

哎呀!我想你是正確的。我們的代碼工作是因爲我們使用了一個名爲EnhancedDataGrid的自定義子類來處理它。它添加了二傳手,但實際上只是移動了孩子。例如,我只是將類名從我們的子類更改爲DataGrid。謝謝你打電話給我。最簡單的方法是添加第二個Collection屬性,並在內部綁定其內容。網格中的代碼只有很小的變化。 – MarqueIV 2012-01-30 04:57:44

+0

謝謝你很好的解決方案。你能告訴我如何根據我的viewmodel上的一些屬性設置網格「樣式」。我有不同的佈局基於相同的數據 – 2014-03-14 12:57:58

1

您可以創建一個自定義控件來包裝數據網格並將數據傳遞給它。控件將設置網格上的數據。

+0

這隻適用於整個網格在所有迭代之間相同,這可能是也可能不是這樣。此外,它限制了可以使用控件模板或其他樣式對它們進行樣式設置,因爲它已將其包裝在UserControl中。 @Queso特別詢問了這些列,這就是爲什麼我建議上述解決方案只針對這些解決方案,並且可以在使用網格的任何地方使用,包括在UserControl中。 – MarqueIV 2011-06-01 00:36:36

0

這個答案是基於MarquelV的解決方案。在他的回答(以及評論)中,他提到了一個名爲EnhancedDataGrid的自定義控件,在那裏他提供了集合DataGrid.Columns屬性的邏輯。下面是一個EnhancedDataGrid代碼:

public class EnhancedDataGrid : DataGrid 
    { 
     //the dependency property for 'setting' our columns 
     public static DependencyProperty SetColumnsProperty = DependencyProperty.Register(
      "SetColumns", 
      typeof (ObservableCollection<DataGridColumn>), 
      typeof (EnhancedDataGrid), 
      new FrameworkPropertyMetadata 
      { 
       DefaultValue = new ObservableCollection<DataGridColumn>(), 
       PropertyChangedCallback = EnhancedDataGrid.SetColumnsChanged, 
       AffectsRender = true, 
       AffectsMeasure = true, 
       AffectsParentMeasure = true, 
       IsAnimationProhibited = true, 
       DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, 
      }); 

     //callback to reset the columns when our dependency property changes 
     private static void SetColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var datagrid = (DataGrid) d; 

      datagrid.Columns.Clear(); 
      foreach (var column in (ObservableCollection<DataGridColumn>)e.NewValue) 
      { 
       datagrid.Columns.Add(column); 
      } 
     } 

     //The dependency property wrapper (so that you can consume it inside your xaml) 
     public ObservableCollection<DataGridColumn> SetColumns 
     { 
      get { return (ObservableCollection<DataGridColumn>) this.GetValue(EnhancedDataGrid.SetColumnsProperty); } 
      set { this.SetValue(EnhancedDataGrid.SetColumnsProperty, value); } 
     } 
    } 

現在你可以設置與SetColumns列依賴於你的CustomControl創建屬性:

<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo1}" /> 
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo2}" /> 
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo3}" /> 
相關問題