2011-07-30 28 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

相关问题