2012-09-27 14 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); 
     }; 
    } 
} 
相关问题