2011-07-30 51 views
2

我想將對象的集合綁定到Silverlight中的DataGrid。該對象屬於以下類型:動態地將字典中的字段綁定到Silverlight DataGrid

public class Seats 
{ 
    Dictionary<Group, long> dctValues = new Dictionary<Group, long>(); 

    public int Id { get; set; } 

    public Dictionary<Group, long> Values 
    { 
     get { return dctValues; } 
    } 
} 

然而,集團由下式表示:

public class Group 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

我希望能夠基於組的字典,其中每列將有生成列標頭設置爲Group.Name,並且每個項目的單元格值等於字典中long值。

+0

到目前爲止,我們在該列中有一個標題欄和一個單元格值。您希望該列還有多少其他單元格? IOW行從哪裏來? – AnthonyWJones

+0

假設我們有列表包含5個項目,其中每個項目將有3個組分別具有其名稱屬性「GroupA」,「GroupB」和「GroupC」。 的5個項目被劃分如下: 項目1:ID:1,A組:100,組B:200,C組:300 項目2:ID:2,A組:1000,組B:2000,C組:3000 – SiN

+0

確定下一個可能需要考慮的問題。兩個不同的'Seats'實例(這個'List '中的每個成員)都在其各自的'Values'字典中有一個條目,名爲GroupA。他們是否都引用單個「Group」實例__或___他們各自有不同的'Group'實例,它們碰巧具有相同的'Id'和'Name'值? – AnthonyWJones

回答

4

我打算假設我們不能保證每個組名稱只有一個Group類的單個實例。 (?否則你將根據已知組的列表上生成列沒有)

這裏是DataGrid派生的類:

public class SeatsGrid : DataGrid, IValueConverter 
{ 
    public SeatsGrid() 
    { 
     AutoGenerateColumns = false; 
    } 
    #region public List<Seats> SeatsList 

    public List<Seats> SeatsList 
    { 
     get { return GetValue(SeatsListProperty) as List<Seats>; } 
     set { SetValue(SeatsListProperty, value); } 
    } 

    public static readonly DependencyProperty SeatsListProperty = 
     DependencyProperty.Register(
      "SeatsList", 
      typeof(List<Seats>), 
      typeof(SeatsGrid), 
      new PropertyMetadata(null, OnSeatsListPropertyChanged)); 

    private static void OnSeatsListPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     SeatsGrid source = d as SeatsGrid; 
     List<Seats> value = e.NewValue as List<Seats>; 
     source.OnSeatsListPropertyChanged(value); 
    } 

    private void OnSeatsListPropertyChanged(List<Seats> value) 
    { 
     ItemsSource = null; 
     Columns.Clear(); 

     var groups = value 
      .SelectMany(seats => seats.Values.Keys) 
      .Select(g => g.Name) 
      .Distinct(); 

     foreach (var group in groups) 
     { 
      DataGridTextColumn col = new DataGridTextColumn(); 
      col.Binding = new Binding() 
      { 
       Converter = this, 
       ConverterParameter = group 
      }; 
      col.Header = group; 
      Columns.Add(col); 
     } 

     ItemsSource = value; 
    } 
    #endregion public List<Seats> SeatsList 

    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Seats seats = (Seats)value; 
     string group = (string)parameter; 

     Group actualGroup = seats.Values.Keys.FirstOrDefault(g => g.Name == group); 
     if (actualGroup != null) 
     { 
      return seats.Values[actualGroup].ToString(); 
     } 
     else 
     { 
      return null; 
     } 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

將這個類在XAML中的實例,並指定一個List<Seats>SeatsList屬性,它會生成列並呈現行。

它是如何工作的?

魔法開始於OnSeatsListPropertyChanged方法。它首先獲得不同組名稱的列表。它爲每個組名稱生成一個新的文本列,自然將該標題設置爲組名。

設置列的綁定時出現奇怪的東西。綁定被賦予一個轉換器,爲了便利,我決定在SeatsGrid類中實現。轉換器參數是組名稱。由於沒有指定路徑,因此在實際發生綁定時,整個Seats對象將被傳遞給轉換器。

現在看着IValueConverter.Convert方法。它在與轉換器參數名稱相同的座位中找到Group的實例(是任何)。如果找到則使用Group作爲查找返回值的關鍵。

如果已知羣組是每個名稱都是唯一的,那麼代碼可以簡化,但原理是相同的。

+0

完美!轉換器實際上做到了。非常感謝! – SiN

相關問題