2012-11-11 61 views
1

我使用mvvm-light,我注意到了關於RaisePropertyChanged的這種奇怪行爲。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( 「文集」),不更新的結合而RaisePropertyChanged(」文字「)。我可以通過多次執行Command2和Command1來看到它。如果集合是一個ObservableCollection,則新元素在視圖中顯示,但更新的項目不是,這意味着ObservableCollection的內部機制起作用,但不是RaisePropertyChanged。

+0

你是否爲你的A類實現了'INPC'? –

+0

@ RV1987,ObservableObject實現。 – aush

+0

只要您設置的屬性正在提升'PropertyChanged'事件,UI就會更新。 –

回答

4

首先,這個問題的解釋:

在Windows Phone上,設置一個依賴屬性的值時,該框架在內部檢查,如果新的值是從舊的(優化的目的也許)不同。當您提出PropertyChanged事件或直接將集合重新分配給ItemsSource屬性(這只是ItemsControl.ItemsSourceProperty依賴項屬性的包裝)時,框架檢測到該值實際上沒有更改並且不更新該屬性。因此,ListBox永遠不會收到您的更改通知,並且不會更新。

ObservableCollection的作品,因爲它採用了完全不同的機制:ListBox直接預訂了CollectionChanged事件您的收藏,因而不被依賴特性的侷限性阻礙。


現在,如何解決這個限制?我能想到的唯一解決方法是:

  1. 使用的ObservableCollection而不是List
  2. 分配null到您的ListBoxItemsSource屬性,然後重新分配您的收藏
  3. 綁定ListBox到財產,將返回不同的集合,每次它被稱爲:

    public List<A> CollectionCopy 
    { 
        get 
        { 
         return this.Collection.ToList(); 
        } 
    } 
    
相關問題