将DataGridView与BindingList一起使用<t>其中T是接口和跨线程更新</t>

时间:2013-03-14 11:29:03

标签: c# .net winforms datagridview multithreading

当我有这样的界面时:

public interface IClass
{
    string { get; set;}
}

继承接口的类:

using System.Runtime.CompilerServices;

public class MyClass : INotifyPropertyChanged : IClass
{
    private string name;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get { return name;}
        set
        {
            name = value;
            this.NotifyPropertyChanged();
        }
    }    

    public MyClass(string name)
    {
        this.Name = name;
    }

    private void NotifyPropertyChanged([CallerMemberName] string caller = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(caller));
        }
    }
}

我将DataGridView数据源绑定到BindingList,如下所示:

BindingList<MyClass> classes = new BindingList<MyClass>();

MyClass testClass = new MyClass("test1");
MyClass testClass = new MyClass("test2");
classes.Add(testClass);

dataGridView1.DataSource = classes;

只要name属性从另一个表单更改,datagridview就会更新。但是,当我尝试执行以下操作时,它不起作用。

BindingList<IClass> classes = new BindingList<IClass>();

MyClass testClass = new MyClass("test");
MyClass testClass = new MyClass("test2");
classes.Add(testClass);

dataGridView1.DataSource = classes;

我可能已经跟踪了这个问题,当我使用BlassList for IClass时,PropertyChanged事件在进行属性更新时为null。但是,对于MyClass使用BindingList它不是null。为什么呢?

这个想法是可能有MyClassA,MyClassB等具有可以在datagridview中显示的相同属性。

其他问题:如果在非UI线程中运行MyClass并进行更新,该怎么办?我是否必须保留对线程编组的主窗体或控件的引用?或者这只是简单的糟糕设计?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您的MyClass继承自INotifyPropertyChanged和IClass。这就是为什么在BindingList中使用MyClass时会触发PropertyChanged事件的原因。

另一方面,IClass不会从INotifyPropertyChanged继承,因此它无法访问它的PropertyChanged事件处理程序。这就是为什么在BindingList中使用IClass时,PropertyChanged事件不会触发的原因。

尝试改变这样的继承顺序。

public interface IClass : INotifyPropertyChanged 
    {
        string Name { get; set;}
    }


public class MyClass: IClass
    {
        private string name;

        public event PropertyChangedEventHandler PropertyChanged;

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                this.NotifyPropertyChanged("Name");
            }
        }

        public MyClass(string name)
        {
            this.Name = name;
        }

        private void NotifyPropertyChanged(string caller = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(caller));
            }
        }

我测试了它。它有效。