2010-06-28 55 views
1

这个问题可能是个坏一流的设计和无知来更新一个动态的领域 - 请多多包涵:如何使用的ObservableCollection上的Silverlight数据网格

我有2个班 - 芯片(其中实现INotifyPropertyChanged,并表示单个筹码)和ChipSet,它实现INotifyPropertyChanged并具有Chip的ObservableCollection。

我有一个Datagrid绑定到Chip ObservableCollection和一个绑定到ChipSet的Textblock。

即。 gridChips.ItemsSource = chipset.Chips;

芯片类有3个属性(为简单起见) - NumberPerPlayer,ChipValue和TotalValuePerPlayer。 TotalValuePerPlayer没有像其他2那样的属性集或关联的私有成员变量 - 它动态地基于ChipValue和NumberPerPlayer的产品。

网格绑定到所有这3个值并显示这3列。只有前2个是可编辑的,而第3个更新为其他2个更改。

目前为止工作正常 - 我发现为了让TotalValuePerPlayer列更新,如果任何其他列更新,我必须将此字段添加到PropertyChangedEventArgs(请参阅下面的代码)。

我的第一个问题是这是更新基于其他字段的绑定类字段的最佳方式,并且不会在UI中更改(您无法直接编辑TotalValuePerPlayer)。

public int NumberPerPlayer 
{ 
    get { return numberPerPlayer; } 
    set 
    { 
     if (numberPerPlayer != value) 
     { 
      numberPerPlayer = value; 
      OnPropertyChanged("NumberPerPlayer"); 
      OnPropertyChanged("TotalValuePerPlayer"); 
     } 
    } 
} 

public decimal ChipValue 
{ 
    get { return chipValue; } 
    set 
    { 
     if (chipValue != value) 
     { 
      chipValue = value; 
      //all columns that are based on this need to be updated 
      OnPropertyChanged("ChipValue"); 
      OnPropertyChanged("TotalValuePerPlayer"); 
    } 
} 

公共小数TotalValuePerPlayer { {返回chipValue * numberPerPlayer; }}

public void OnPropertyChanged(string propertyName) 
{ 
    if (PropertyChanged != null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

我的第二,主要的问题是这样的:当时我有一个标签,该标签显示了总所有TotalValuePerPlayer总计(愚蠢称为TotalTotalValuePerPlayer)。我把这个芯片组类这样的(它通过的ObservableCollection迭代,并总结了总数):

1   public decimal TotalTotalValuePerPlayer 
2   { 
3    get { 
4   decimal totalTotalValuePerPlayer = 0; 
5     foreach (Chip chip in chips) 
6     { 
7      totalTotalValuePerPlayer += chip.TotalValuePerPlayer; 
8     } 
9     return totalTotalValuePerPlayer; 
10  } 
11   } 

所以 - 问题是,当任何一个2列(NumberPerPlayer或ChipValue)这个领域是基于在UI更改中,它不会更新。

如何告诉父类--ChipSet,当它的ObservableCollection中的某个子类(Chip)成员中的某个成员被更新时,它有更新的TotalTotalValuePerPlayer成员?

如果TotalTotalValuePerPlayer在Chip类中,那么当它基于的字段发生变化时,我可以通知它,但它在上面的类中?

感谢您的任何建议!

罗德尼

回答

1

您好,我相信你会解决这个你只需再前进一步的正确方法。下面是如何期望的类看:

芯片

public class Chip : INotifyPropertyChanged 
{ 
    private int numberPerPlayer; 
    public int NumberPerPlayer 
    { 
     get { return numberPerPlayer; } 
     set 
     { 
      if (numberPerPlayer != value) 
      { 
       numberPerPlayer = value; 
       OnPropertyChanged("NumberPerPlayer"); 
       OnPropertyChanged("TotalValuePerPlayer"); 
      } 
     } 
    } 

    private decimal chipValue; 
    public decimal ChipValue 
    { 
     get { return chipValue; } 
     set 
     { 
      if (chipValue != value) 
      { 
       chipValue = value; 
       //all columns that are based on this need to be updated 
       OnPropertyChanged("ChipValue"); 
       OnPropertyChanged("TotalValuePerPlayer"); 
      } 
     } 
    } 

    public decimal TotalValuePerPlayer 
    { 
     get 
     { 
      return chipValue * numberPerPlayer; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

芯片组

public class ChipSet : INotifyPropertyChanged 
{ 
    public ChipSet() 
    { 
     foreach (var chip in Chips) 
     { 
      chip.PropertyChanged += (s, e) => { OnPropertyChanged("TotalTotalValuePerPlayer"); }; 
     } 
    } 


    public ObservableCollection<Chip> Chips { get; set; } 

    public decimal TotalTotalValuePerPlayer 
    { 
     get 
     { 
      return Chips.Sum(x => x.TotalValuePerPlayer); 
     } 
    } 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

我还没有完全测试这一点,但它应该指向你在正确的方向。希望能帮助到你。

+0

嗨Blounty, 感谢您花时间回答 - 我有点困惑,我需要做的 - 是芯片组构造函数的外观? chip.PropertyChanged + =(s,e)=> {OnPropertyChanged(“TotalTotalValuePerPlayer”); }; 你是否在Chip类上连接了一个事件处理器?你是否介意完整地写出这个循环,因为我不完全确定你的意思 - 非常感谢! – Rodney 2010-06-28 17:55:45

+0

Hi Rodney,ChipSet构造函数中的所有代码正在执行,正在循环遍历ObservableCollection 中的Chips并附加到每个Chip的PropertyChanged事件。这是因为当Chip的任何一个属性改变时,它都会将ChipSet的TotalTotalValuePerPlayer更新为UI。 – Blounty 2010-06-29 07:18:45

+0

太棒了,谢谢Blounty(花了我一段时间才弄清楚这个语法 - 这对我来说是新的!) – Rodney 2010-06-29 16:56:57

相关问题