Winforms包含List <t> </t>的数据绑定对象

时间:2009-07-13 15:06:14

标签: c# winforms data-binding

我遇到了一个我知道必须非常普遍的情况,所以我希望解决方案很简单。我有一个包含List&lt;&gt;的对象对象它还有一些属性反映了List&lt;&gt;中对象的聚合数据。 (实际上是BindingList&lt;&gt;所以我可以绑定它)。在我的表单上,我有一个List的DataGridView,以及聚合数据的一些其他字段。当DataGridView中的值发生变化时,我无法弄清楚如何触发聚合数据的刷新。

我已尝试在更改List中对象的属性时引发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
}
}

2 个答案:

答案 0 :(得分:3)

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));
        }
    }
}

现在,当列表项中的属性发生更改时,父对象将触发属性更改事件,并且绑定到它的任何内容也应该更改。

答案 1 :(得分:-1)

我相信你可能正在寻找类似的东西

ITypedList

同样,Google Search的ITypedList会引导您找到一些关于如何实施的好博客。

当我使用ORM时,我通常需要做一些这些以获得良好的数据网格绑定和表示。