トップ > Tech > CSharp > WPF > バインディングオブジェクト内の変更をコントロールに反映するには

バインディングオブジェクト内の変更をコントロールに反映するには

概要

WPF でコントロールにオブジェクトを Binding している場合、オブジェクトのプロパティが変更されたときにコントロールの表示も伴って更新されてほしいわけだが、残念ながら更新されない。

これは、更新されたことを通知する機構がオブジェクトに備わっていないからである。 このページではこれの対応策を示す。

対策

まず INotifyPropertyChanged インターフェースを実装

コントロールにプロパティが変更されたことを通知するには、まずバインドするクラスに INotifyPropertyChanged インターフェースを実装しておく。

INotifyPropertyChanged を実装すると PropertyChanged イベントが追加されるので、これをコールするための下記のようなメソッドを作っておく。

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
    }
}

この引数 name には変更されたプロパティの名前を渡す。

そして変更を通知すべきプロパティ(表示を更新する必要のあるプロパティ)の set アクセサで次のようにコールする。

private string _userId;
public string UserId
{
    get
    {
        return _userId;
    }
    set
    {
        _userId = value; 
        OnPropertyChanged("UserId");
    }
}

これで UserId に値がセットされると、変更が通知されるようになる。

コレクションには ObservableCollection<T> クラス

たとえば TreeView に階層構造のオブジェクトをバインドしているとする。

オブジェクトの中のコレクションを List<T> などで実装しているとこれらのコレクションに要素が追加もしくは削除されたとき、TreeView の表示が更新されない。 また、これはコレクションのプロパティから PropertyChanged を呼んでも同じである。

これを自動的に反映されるようにするにはコレクションに ObservableCollection<T> クラスを利用すればいい。

ソースコード

以上の実装例を示す。

public class TopLevel : System.ComponentModel.INotifyPropertyChanged
{
    private string _userId;
    public string UserId
    {
        get
        {
            return _userId;
        }
        set
        {
            _userId = value; 
            OnPropertyChanged("UserId");
        }
    }

    public ObservableCollection<SecondLevel> SecondLevels { get; set; } }
    
    #region INotifyPropertyChanged メンバー

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(name));
        }
    }

    #endregion
}

参考

(2010/09/15 13:51:34)
47761
プロフィール

Kenz Yamada(山田研二)。1984年生。大阪。ちょっとずつ好きなプログラム作ってます。 好きなものはカメラと旅行。ガジェットや身の回り、ちょっとこだわります。 詳しくは Web mixi で。

Bookmark and Share