我遇到一种情况,我知道那一定很普遍,因此遇到了麻烦,所以我希望解决方案很简单。我有一个包含对象的List 的对象。它还具有一些属性,这些属性反映了List 中的对象的聚合数据(实际上是BindingList ,因此我可以绑定到它)。在我的表单上,我有一个用于列表的DataGridView,以及一些用于汇总数据的字段。当DataGridView中的值更改时,我无法弄清楚如何触发聚合数据的刷新。当列表中的对象的属性发生更改时,我尝试引发PropertyChanged事件,但这似乎无法刷新聚合数据的显示。如果我访问聚合属性(例如,在消息框中显示它),则刷新主窗体上的文本框。这是一些简化的代码来说明我正在尝试做的事情:namespace WindowsFormsApplication1 {public class Person { public int Age { get; set; } public String Name { get; set; }}public class Roster : INotifyPropertyChanged { public BindingList<Person> People { get; set; } public Roster () { People = new BindingList<Person>(); } private int totalage; public int TotalAge { get { calcAges(); return totalage; } set { totalage = value; NotifyPropertyChanged("TotalAge"); } } private void calcAges () { int total = 0; foreach ( Person p in People ) { total += p.Age; } TotalAge = total; } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged ( String info ) { if ( PropertyChanged != null ) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } #endregion}} (adsbygoogle = window.adsbygoogle || []).push({}); 最佳答案 calcAges方法和TotalAge属性看起来非常可疑。首先,TotalAge应该是只读的。如果您允许它公开且可写,那么更改构成年龄的组件的逻辑是什么?其次,每次获取值时,您都会触发PropertyChanged事件,这不是很好。您的Roster类应如下所示:public class Roster : INotifyPropertyChanged { public Roster () { // Set the binding list, this triggers the appropriate // event binding which would be gotten if the BindingList // was set on assignment. People = new BindingList<Person>(); } // The list of people. BindingList<Person> people = null; public BindingList<Person> People { get { return people; } set { // If there is a list, then remove the delegate. if (people != null) { // Remove the delegate. people.ListChanged -= OnListChanged; } /* Perform error check here */ people = value; // Bind to the ListChangedEvent. // Use lambda syntax if LINQ is available. people.ListChanged += OnListChanged; // Technically, the People property changed, so that // property changed event should be fired. NotifyPropertyChanged("People"); // Calculate the total age now, since the // whole list was reassigned. CalculateTotalAge(); } } private void OnListChanged(object sender, ListChangedEventArgs e) { // Just calculate the total age. CalculateTotalAge(); } private void CalculateTotalAge() { // Store the old total age. int oldTotalAge = totalage; // If you can use LINQ, change this to: // totalage = people.Sum(p => p.Age); // Set the total age to 0. totalage = 0; // Sum. foreach (Person p in People) { totalage += p.Age; } // If the total age has changed, then fire the event. if (totalage != oldTotalAge) { // Fire the property notify changed event. NotifyPropertyChanged("TotalAge"); } } private int totalage = 0; public int TotalAge { get { return totalage; } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged ( String info ) { if ( PropertyChanged != null ) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } }}现在,当列表项中的属性发生更改时,父对象将触发属性更改事件,并且与其绑定的所有内容也应更改。 (adsbygoogle = window.adsbygoogle || []).push({});
10-08 08:01