如何在Silverlight数据网格上使用ObservableCollection更新动态字段

时间:2010-06-28 09:21:14

标签: binding silverlight-4.0

这个问题可能是糟糕的课堂设计或无知 - 请耐心等待:

我有2个类 - Chip(实现INotifyPropertyChanged并代表单个扑克筹码)和ChipSet,它实现了INotifyPropertyChanged并且有一个ObservableCollection of Chip。

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

即。 gridChips.ItemsSource = chipset.Chips;

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

网格绑定到这3个值中的所有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     {         get {return chipValue * numberPerPlayer; }     }

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

我的第二个,主要问题是:我有一个标签,显示所有TotalValuePerPlayer总数(愚蠢地称为TotalTotalValuePerPlayer)的总和。我把它放在这样的ChipSet类中(它遍历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           }

所以 - 问题是当这两个字段(NumberPerPlayer或ChipValue)中的任何一个字段基于UI更改时,它都不会更新。

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

如果TotalTotalValuePerPlayer在Chip类中,我可以在基于它的字段发生更改时通知它,但是它在上面的类中?

感谢您的任何建议!

罗德尼

1 个答案:

答案 0 :(得分: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;
}

我没有对此进行过全面测试,但它应该指向正确的方向。希望它有所帮助。