2009-12-07 28 views
3

有沒有辦法使用綁定聲明式指定DataGrid列? (並設置列的屬性使用此綁定?) Idealy,我會有一個對象列表(例如行)的數據綁定到ItemsSource和他們的屬性之一將是一個字典(或一個特定類的對象列表或任何)與名稱和價值。我希望DataGrid能夠自動創建這些額外的列,而不需要隱藏一些代碼。這甚至有可能嗎?或者你如何解決這個問題?使用綁定以聲明方式指定並顯示WPF中的DataGrid的列?

保存額外值的數組可能會隨時間而改變,但對列表中的所有項目都是一樣的。

這將是可能的(和清潔)爲DataGrid提供一個不同的列表,只是爲了創建列。但是,我需要像ColumnsSource或東西...

,我能想出是創造DataGrid的一個子類的唯一的事情...

任何想法?

編輯: 的一點是不落後任何代碼實現這個...

回答

1

在冠冕堂皇的有爭議的風險...

我覺得這是一個例子,其視圖確實需要一點點代碼「升壓」,而「無代碼隱藏」指南可放一邊 - 只要你記得保持你的關注分離。

我過去通過從ViewModel獲取相關數據動態創建DataGrid控件,並在代碼隱藏中編寫類似於部分答案的'BuildDataGrid'方法。 我認爲這是有道理的,因爲代碼完全關注補充視圖,而且我沒有通過實現業務規則來混合關注點 - 它只是將這些列放在一起,並根據需要創建了Bindings列。

但是,如果讓代碼保持清潔更重要,那麼我會建議您創建用戶控件的原創想法,並使用DP來控制「子類」。

+0

我想這是唯一的方法,我會保持打開一段時間的問題,也許有人會想出一些東西,否則接受這一點。 只是一個旁註:網格能夠自動生成額外的列(AutoGenerateColumns屬性)。但這當然不起作用或列表。問題是,整個綁定是否可以與匿名類一起工作?或者更好 - 是否使用反射來生成額外的列?我可以爲數據創建一個動態類,但在可維護性和可讀性方面可能會更糟...... – 2009-12-08 14:39:55

+0

我知道這並不理想...... MV-VM發展得如此巨大,因爲此控件最初是作者創作的,我相信將來會有一個版本將列作爲DP進行公開。在此之前,我想我們必須選擇最實用的解決方案....乾杯, – kiwipom 2009-12-08 17:29:09

+1

我知道這是舊的,但我已經注意到,取決於操作系統(也許是否安裝.Net 4.5,即使在目標.Net 4.0),設置AutoGenerateColumns = true確實在Windows 7中使用反射。因此,您可以返回一個IEnumerable (或動態)(順便提一句,List impliments),並讓DataGrid生成列,甚至可以從匿名類型。但是,如果您希望在XP上運行,那麼您需要以某種方式對自己的代碼進行動態生成列。 – William 2013-02-28 18:58:31

1

在您的XAML來DataGrid綁定到某一類具有的屬性對象的ObservableCollection。

XAML:

<WpfToolkit:DataGrid 
     x:Name="MyDataGrid" 
     ItemsSource="{Binding Path=Collection}" 
     HorizontalScrollBarVisibility="Hidden" SelectionMode="Extended" 
     CanUserAddRows="False" CanUserDeleteRows="False" 
     CanUserResizeRows="False" CanUserSortColumns="False" 
     AutoGenerateColumns="False" 
     RowHeaderWidth="25" RowHeight="25"/> 

接下來,您可以在C#/ VBA編程方式創建列和每一列綁定到類,其中的ObservableCollection,包含了對象的屬性。通過添加類的對象,您將向數據網格添加行。換句話說,ObservableCollection中類的每個對象都是一行,並且該類的屬性將成爲列。

下面是一個例子,如何通過編程綁定你列... C#:

ObservableCollection<IData> datagridData = new ObservableCollection<IData>(); 
Binding items = new Binding(); 
PropertyPath path = new PropertyPath("Name"); // 'Name' is actually the name of the variable representing the property 
items.Path = path; 

MyDataGrid.Columns.Add(new DataGridTextColumn() 
{ 
    Header = "Names", 
    Width = 275, 
    Binding = items 
}); 
//repeat the creation of columns 
//... 
//- Add some objects to the ObservableCollection 
//- Then bind the ItemsSource of the datagrid to the ObservableCollection 
datagridData .Add(new Data("Bob", string.Empty)); 
MyDataGrid.DataContext = new DataModel{ MyData = datagridData }; 

*編輯: 對此深感抱歉!這裏是你如何能完全實現同樣的事情在XAML:

<WpfToolkit:DataGrid 
     x:Name="MyDataGrid" 
     ItemsSource="{Binding Path=Collection}" 
     HorizontalScrollBarVisibility="Hidden" SelectionMode="Extended" 
     CanUserAddRows="False" CanUserDeleteRows="False" 
     CanUserResizeRows="False" CanUserSortColumns="False" 
     AutoGenerateColumns="False" 
     RowHeaderWidth="25" RowHeight="25"> 

      <WpfToolkit:DataGridTextColumn 
         Header="Names" Width="2*" 
         Binding="{Binding Path=Name}"/> 
      <WpfToolkit:DataGridTextColumn 
         Header="Names" Width="2*" 
         Binding="{Binding Path=Age}"/> 

     </WpfToolkit:DataGrid.Columns> 
</WpfToolkit:DataGrid> 

編輯2:這裏是的ObservableCollection和類的代碼可能看起來像在C#:

public class DataModel 
    { 
     public ObservableCollection<IData> MyData{ get; set; } 
    } 

public interface IData 
    { 
     string Name{ get; set; } 
     string Age{ get; set; } 
    } 

public class Data : IData 
    { 
     public Data(string name, string age) 
     { 
      Name= name; 
      Age= age; 
     } 

     public string Name{ get; set; } 
     public string Age{ get; set; } 
    } 
+0

是的,這是近乎完美的,只有一個小例外......我不想以編程方式編寫它。這就是爲什麼標題中有「聲明式」的原因。我會更新這個問題以使其更清楚。但感謝您的意見! – 2009-12-08 00:17:16

+0

再次錯過我很害怕。這個例子中的列是硬編碼的,不是由綁定生成的。 (列的內容綁定到屬性,這很好,但列本身不是......) 另外,網格可能有一些硬編碼列,但其餘列應該從列表中生成。 (IData會有另一個屬性,可以說是一個Disctionary,額外的列將是該discallyary的關鍵,我不認爲這是可能的,所以我基本上尋找一種方法來解決它) – 2009-12-08 14:34:42

0

我想你會必須繼承網格。列不是可綁定的屬性。如果你不能綁定它,你不能動態地在xaml中擺弄它。

至於使用項目來創建列,這是否意味着如果網格中沒有項目將不會有列?

如果您有一個可以綁定到列屬性的網格的子類,那麼動態更改列的位置將位於您的視圖模型中。

+0

你可以綁定專欄! – Partial 2009-12-08 04:12:13

+1

是啊..好嗎?它是一個 public ObservableCollection Columns {get; }屬性。如果你不能設置它,你怎麼能綁定它? – 2009-12-08 04:27:59

+0

編號喜歡看到一個例子,如果你有一個...如果不是像一個upvote的ID – 2009-12-08 04:48:32