17

UIにObservableCollectionのプロパティにバインドされたListBoxがあります。ObservableCollectionの新しいインスタンスをビューモデルのコンストラクターのプロパティに設定し、フォームのボタンを使用してアイテムを追加できます。これらはリストに表示されます。

すべてが良いです。

ただし、ボタンコールバックでnewを使用してプロパティを再初期化すると、バインディングが壊れ、UIにコレクションの内容が表示されなくなります。

バインディングは引き続きプロパティの値を検索すると想定しましたが、おそらく新しいによって破棄される参照にリンクされています。

私はこれを正しく理解しましたか?誰かがこれがどのようにリンクされているかについて拡張できますか?ビューモデルにビューの知識がない場合に再バインドする方法はありますか?

4

4 に答える 4

14

コレクションを再初期化した後、必ず PropertyChangedEvent を発生させてください。このイベントを発生させると、モデルがビューを認識しない状態で、ビューがプロパティへの変更を処理できるようになります。

class Model : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

    private ObservableCollection<string> _list = new ObservableCollection<string>();
    public ObservableCollection<string> List
    {
        get { return _list; }
        set 
        { 
            _list = value;
            NotifyPropertyChanged("List");
        }
    }

    public Model()
    {
        List.Add("why");
        List.Add("not");
        List.Add("these?");
    }
}
于 2013-02-09T01:06:11.093 に答える
4

あなたの説明に基づいて、ObservableCollection を公開するプロパティをリファクタリングして、新しい値が割り当てられたときにも PropertyChanged イベントが発生するようにする必要があると思います。例:

public ObservableCollection<int> Integers
{
    get { return this.integers; }
    set {
        if (this.integers != value)
        {
            this.integers = value;
            RaisePropertyChanged("Integers");
        }
    }
}
于 2013-02-09T01:06:23.577 に答える
3

ViewModel に INotifyPropertyChanged を実装したと仮定すると、ObservableCollection に新しい値を割り当てるたびにプロパティ変更イベントを発生させることができます。

public ObservableCollection<string> MyList { get; set; }

public void SomeMethod()
{
    MyList = new ObservableCollection<string>();
    RaisePropertyChanged("MyList");
}
于 2013-02-09T01:06:47.560 に答える
2

への更新は、イベントObservableCollectionにフックすることによって処理されるため、新しいオブジェクトを作成しても、オブザーバーは古いコレクションを見ています。CollectionChangedObservableCollection

2 つの簡単な提案はINotifyPropertyChanged、 を含むクラスに実装し、コレクション プロパティのセッターでイベントを発生さObservableCollectionせることPropertyChangedです (それが独自のコードである場合は、まずオブザーバーで古いものからフックを解除することを忘れないでください)。

private ObservableCollection<string> _myCollection = new ObservableCollection<string>();
public ObservableCollection<string> MyCollection
{
    get { return _myCollection; }
    set
    {
        if(_myCollection == value)
            return;

        _myCollection = value;
        RaisePropertyChanged("MyCollection");
    }
}

次に、私が一般的に好むオプションは、コレクションが到着したときに新しいデータをクリアして再入力することです。

public void HandleCollectionData(IEnumerable<string> incomingData)
{
    MyCollection.Clear();
    foreach(var item in incomingData)
    {
        MyCollection.Add(item);
    }
}
于 2013-02-09T01:11:47.167 に答える