3

Winforms .net 3.5 アプリ。私のアプリには、次のようなジェネリック クラスがあります。

public class FilterItem {
  public FilterItem() { }
  public string FilterProperty { get; set; }
  public bool FilterPropertyChecked { get; set; }
  public ComparitiveOperator FilterOperator { get; set; }
  public string FilterValue { get; set; }
}

ある種のフィルター機能を実装したい場合は、すべてのダイアログ ボックスで使用します。そのため、コンストラクターに渡された事前に入力されたダイアログ フォームを呼び出しますList<FilterItem>。ダイアログが読み込まれると、各リスト項目を反復処理して以下を追加します。

  1. チェックボックス
  2. コンボボックス
  3. テキストボックス

TableLayoutPanel のすべての行に。Checkbox は からテキスト プロパティを取得しFilterProperty、Checked ステータスは からFilterPropertyChecked取得します。Combobox は からバインドをFilterOperator取得し、Textbox は からテキスト値を取得しますFilterValue

私がget とだけ言っていることに注意してください。私がやりたいことは、プロパティが変更されるコントロールがバインドされているときに、これらのプロパティを自動的に更新することです。聞いたことObservableCollection<T>がありますが、名前空間を追加した後、Winforms で「アクセス」できないようですSystem.Collections.ObjectModel

これを達成するための最良の方法は何でしょうか。INotifyPropertyChanged を使用した BindingList?? 私は後者の専門家ではなく、いくつかの指針を大いに感謝します-これが私が進むべき道である場合.

ありがとう!

編集:

わかりました、私がやるべきだと思うことを示すためにいくつかのコードを投稿させてください:)。FilterItem クラスに実装する必要があることはわかっているINotifyPropertyChangedので、(たとえば FilterValue 部分のみ):

public class FilterItem : INotifyPropertyChanged {
    public FilterItem() { }
    public string FilterProperty { get; set; }
    public bool FilterPropertyChecked { get; set; }
    public ComparitiveOperator FilterOperator { get; set; }

    private string _FilterValue;
    public string FilterValue {
        get { return this._FilterValue; }
        set {
            if (this._FilterValue != value) {
                this._FilterValue = value;
                this.OnFilterValueChanged();
            }
        }
    }

    #region INotifyPropertyChanged Members
    protected void OnFilterValueChanged() {
        var handler = this.PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs("FilterValue"));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion
}

これで、次のようにすべてが Form_Load にまとめられるはずです (これは Textbox 部分のみで、Checbox と ComboBox は省略しました)。

private List<FilterItem> FilterList; // <-- this gets assigned to in the constructor

private void dlgFilterData_Load(object sender, EventArgs e) {
    foreach (FilterItem item in FilterList) {
        txt = new TextBox();
        txt.DataBindings.Add("Text", item, "FilterValue", false, DataSourceUpdateMode.OnPropertyChanged);
        txt.Dock = DockStyle.Fill;
    }
}

テキストボックスのデータバインディング DataSource は FilterItem 'item' です。しかし、今は私のビジュアル スタジオ IDE に問題があるようです。私が今知りたいのは、このセットアップはFilterItem、割り当てられたコントロールのそれぞれのプロパティが変更されたときに、個々の を自動的に更新できるようにするのに役立ちますか??

4

1 に答える 1

3

ObservableCollection クラスは WindowsBase アセンブリに含まれているため、「アクセス」するにはプロジェクト参照に WindowsBase を追加する必要があります。

そうは言っても、ObservableCollection で必要なものがすべて得られるとは思いません。アイテムを追加または削除すると、バインドされたコントロールに通知が届きますが、プロパティの自動変更通知はありません。

最終的に使用するコレクションの種類に関係なく、INotifyPropertyChanged で正しい方向に進んでいると思います。INotifyPropertyChanged を実装する簡単な例を次に示します。

class Foo : INotifyPropertyChanged
{
    #region Bar property

    private string _bar;
    public string Bar
    {
        get { return _bar; }
        set
        {
            if (_bar != value)
            {
                _bar = value;

                OnPropertyChanged("Bar");
            }
        }
    }

    #endregion

    protected void OnPropertyChanged(string name)
    {
        var handler = PropertyChanged;

        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

基本的に、オブジェクトのプロパティが変更されるたびに、PropertyChanged イベントを発生させ、変更されたプロパティの名前を渡します。

最後に、オブジェクトのプロパティにバインドされたコントロールへの変更に応じて、オブジェクトのプロパティの値を変更したいと言ったので、これはすべて意味がないかもしれません。通常の Windows フォームのデータ バインディング インフラストラクチャでは、INotifyPropertyChanged やその他のインターフェイスを使用しなくても、これを実現できます。INotifyPropertyChanged を実装する必要があるのは、別の場所からオブジェクトのプロパティへの変更をバインドされたコントロールに通知する必要がある場合のみです。

于 2009-11-23T02:14:05.533 に答える