2

mvvm-light を使用していますが、RaisePropertyChanged に関するこの奇妙な動作に気付きました。

xaml:

<ListBox ItemsSource="{Binding Collection}"/>
<TextBlock Text="{Binding Text}"/>

観測可能なクラス:

public class A : ObservableObject
{
    private string _b;
    public string B
    {
        get { return this._b; }
        set
        {
            this._b = value;
            this.RaisePropertyChanged("B");
        }
    }
}

vm:

public MainViewModel(IDataService dataService) { this.Collection = new List<A>(...); }

public RelayCommand Command1
{
    get
    {
        return this._command1 ?? (this._command1= new RelayCommand(() =>
        {
            this.Collection.Add(new A());
            this.Collection[2].B = "updated";
            this.RaisePropertyChanged("Collection");
            this.RaisePropertyChanged("Text");
        }));
    }
}

public RelayCommand Command2
{
    get { return this._command2?? (this._command2 = new RelayCommand(() => { this.Text++; })); }
}

public List<A> Collection { get; set; }
public int Text { get; set; }

したがって、RaisePropertyChanged("Collection") はバインディングを更新しませんが、RaisePropertyChanged("Text") は更新します。Command2 を数回実行し、その後 Command1 を実行するとわかります。Collection が ObservableCollection の場合、新しい要素はビューに表示されますが、更新されたアイテムは表示されません。つまり、ObservableCollection の内部メカニズムは機能しますが、RaisePropertyChanged は機能しません。

4

1 に答える 1

4

まず、問題の説明:

Windows Phone では、依存関係プロパティの値を設定するときに、フレームワークは新しい値が古い値と異なるかどうかを内部的にチェックします (おそらく最適化のため)。イベントを発生させるか、コレクションをプロパティ (依存関係プロパティの単なるラッパー)PropertyChangedに直接再割り当てすると、フレームワークは値が実際には変更されていないことを検出し、プロパティを更新しません。したがって、 には変更が通知されず、更新されません。ItemsSourceItemsControl.ItemsSourcePropertyListBox

ObservableCollectionまったく異なるメカニズムを使用しているため機能します。 はコレクションListBoxのイベントを直接サブスクライブするためCollectionChanged、依存関係プロパティの制限によって妨げられません。


では、この制限を回避するにはどうすればよいでしょうか。私が考えることができる唯一の回避策は次のとおりです。

  1. ObservableCollectionの代わりに を使用するList
  2. のプロパティに割り当てnullてから、コレクションを再割り当てしますItemsSourceListBox
  3. ListBox呼び出されるたびに異なるコレクションを返すプロパティに をバインドします。

    public List<A> CollectionCopy
    {
        get
        {
            return this.Collection.ToList();
        }
    }
    
于 2012-11-11T17:57:13.917 に答える