2012-09-27 32 views
1

我有一個接受ObservableCollection作爲參數轉換器,我想重新評估它,每當在集合改變的任何項目特定屬性調用轉換器,如果觀察集合在一個對象的屬性更改

例如:可以說,我已綁定一個標籤Person對象與轉換器的集合。轉換器的工作就是數一下那個是女性名單的人數,以及1女或「接受」了2回「有效」,我想轉換到被調用的任何一次隨時隨地的Gender財產Person對象被更改。

我該如何做到這一點?當一個項目被添加或從集合(而不是當該集合中的項目被改變)除去

回答

3

這是你最終,如果你玩足夠長WPF有一個經典問題。

我已經嘗試了各種解決方案,但效果最好的一種是使用像這樣一個的BindingList:

public class WorldViewModel : INotifyPropertyChanged 
{ 
    private BindingList<Person> m_People; 
    public BindingList<Person> People 
    { 
     get { return m_People; } 
     set 
     { 
     if(value != m_People) 
     { 
      m_People = value; 
      if(m_People != null) 
      { 
       m_People.ListChanged += delegate(object sender, ListChangedEventArgs args) 
       { 
        OnPeopleListChanged(this); 
       }; 
      } 
      RaisePropertyChanged("People"); 
     } 
     } 
    } 

    private static void OnPeopleListChanged(WorldViewModel vm) 
    { 
     vm.RaisePropertyChanged("People"); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    void RaisePropertyChanged(String prop) 
    { 
     PropertyChangedEventHandler handler = this.PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(prop)); 
     } 
    } 
} 

然後,只需綁定到人收藏喜歡你將與一個ObservableCollection做,除了綁定將當其項目中的任何財產發生變化時都要重新評估。

而且,請注意,OnPeopleListChanged是靜態的,所以沒有內存泄漏。

而且人應該執行INotifyPropertyChanged。

+0

請告訴我更多關於這是如何工作的。什麼叫OnPeopleListChanged?或者它是如何被調用的? – Paparazzi

+0

@Blam每當引發ListChanged時,OnPeopleListChanged被調用。 ListChanged與ObservableCollection中的CollectionChanged非常相似,只是它還監聽集合的項目內的更改。 –

+0

這只是你通常的方法來提高PropertyChanged事件(我在這裏asusming,你的類實現INotifyPropertyChanged)。我已經添加了完整性代碼。 –

0

甲CollectionChanged事件只拋出。所以當一個項目改變時,轉換器不會被調用。

一個選項:
在Gender屬性集中包含用於評估集合的邏輯,並設置字符串將標籤綁定到的屬性。

寫答案的通用版本從狒狒

public class ObservalbeList<T>: INotifyPropertyChanged 
{ 
    private BindingList<T> ts = new BindingList<T>(); 

    public event PropertyChangedEventHandler PropertyChanged; 

    // This method is called by the Set accessor of each property. 
    // The CallerMemberName attribute that is applied to the optional propertyName 
    // parameter causes the property name of the caller to be substituted as an argument. 
    private void NotifyPropertyChanged(String propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public BindingList<T> Ts 
    { 
     get { return ts; } 
     set 
     { 
      if (value != ts) 
      { 
       Ts = value; 
       if (Ts != null) 
       { 
        ts.ListChanged += delegate(object sender, ListChangedEventArgs args) 
        { 
         OnListChanged(this); 
        }; 
       } 
       NotifyPropertyChanged("Ts"); 
      } 
     } 
    } 

    private static void OnListChanged(ObservalbeList<T> vm) 
    { 
     vm.NotifyPropertyChanged("Ts"); 
    } 

    public ObservalbeList() 
    { 
     ts.ListChanged += delegate(object sender, ListChangedEventArgs args) 
     { 
      OnListChanged(this); 
     }; 
    } 
} 
相關問題