0

次のようなインターフェースがある場合:

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;

IClass に BindingList を使用すると、プロパティの更新時に PropertyChanged イベントが null になるという問題を追跡した可能性があります。ただし、MyClass に BindingList を使用すると、null にはなりません。なんで?

考え方は、datagridview に表示できる同じプロパティを持つ MyClassA、MyClassB などが存在する可能性があるというものです。

追加の質問: MyClass が非 UI スレッドで実行され、更新が行われた場合はどうなりますか。スレッド マーシャリングのために、メイン フォームまたはコントロールへの参照を保持する必要がありますか? それとも、これは単なる悪い設計ですか?

前もって感謝します。

4

1 に答える 1

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

私はそれをテストしました。できます。

于 2013-03-14T12:16:59.740 に答える