2013-02-02 61 views
2

如果我有一个Observable集合,像这样:WPF与where子句绑定可能吗?

public ObservableCollection<SpecialPriceRow> SpecialPriceRows = new ObservableCollection<SpecialPriceRow>(); 

SpecialPriceRow类:

public class SpecialPriceRow : INotifyPropertyChanged 
{ 
    public enum ChangeStatus 
    { 
     Original, 
     Added, 
     ToDelete, 
     Edited 
    } 

    public ChangeStatus Status { get; set; } 
    public string PartNo { get; set; } 

    private decimal _price; 
    public decimal Price 
    { 
     get 
     { 
      return _price; 
     } 
     set 
     { 
      if (value != _price) 
      { 
       _price = value; 
       Status = ChangeStatus.Edited; 
       OnPropertyChanged("Status"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 

难道可以让我在XAML一个标签绑定到物体被说的算。 .. 添加?所以,我能得到这样的:

enter image description here

如果绿色是集合中“添加”对象的个数。我会如何去做这样的事情?

+1

我会尝试不同的绑定:DataConverters或创建getter属性并绑定到它们。 –

回答

0

我不知道任何内置功能来做到这一点。我会在您的数据上下文类中创建一个自定义属性,进行计数并绑定到此。

事情是这样的:

public int AddedCount 
{ 
    get 
    { 
     return SpecialPriceRows.Where(r => r.Status == ChangeStatus.Added).Count(); 
    } 
} 

然后,每当一个项目更改或添加你需要明确提高属性更改为此:

public void AddItem() 
{ 
    ... 
    OnPropertyChanged("AddedCount"); 
} 

然后你只需要在你的XAML绑定代码如:

<TextBlock Text="{Binding AddedCount}" /> 

您可能需要订阅c中的更改事件ollection知道项目何时更改。

备选:

您还可以使用特定的过滤器创建一个ListCollectionView并绑定到其Count属性:

AddedItems = new ListCollectionView(TestItems); 
    AddedItems.Filter = r => ((SpecialPriceRow)r).Status == ChangeStatus.Added; 

在XAML中,那么你会绑定到的这个Count属性:

<TextBlock Text="{Binding AddedItems.Count}" /> 

这样做的好处是它将au主动跟踪集合中添加和删除的项目并自行更新。尽管当项目的属性发生变化而影响过滤器时,您必须手动刷新它。

0

我写了一个ViewModel,它将执行所需的功能,你正在寻找。

class VM : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 
     public ObservableCollection<SpecialPriceRow> _SpecialPriceRows = new ObservableCollection<SpecialPriceRow>(); 
     private int _Original = 0; 
     private int _Added = 0; 
     private int _ToDelete = 0; 
     private int _Edited = 0; 

     public VM() 
     { 
      PropertyChanged = new PropertyChangedEventHandler(VM_PropertyChanged); 

      //The following lines in the constructor just initialize the SpecialPriceRows. 
      //The important thing to take away from this is setting the PropertyChangedEventHandler to point to the UpdateStatuses() function. 
      for (int i = 0; i < 12; i++) 
      { 
       SpecialPriceRow s = new SpecialPriceRow(); 
       s.PropertyChanged += new PropertyChangedEventHandler(SpecialPriceRow_PropertyChanged); 
       SpecialPriceRows.Add(s); 
      } 
      for (int j = 0; j < 12; j+=2) 
       SpecialPriceRows[j].Price = 20; 
     } 

     private void VM_PropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
     } 

     private void SpecialPriceRow_PropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      if (e.PropertyName == "Status") 
       UpdateStatuses(); 
     } 

     public ObservableCollection<SpecialPriceRow> SpecialPriceRows 
     { 
      get 
      { 
       return _SpecialPriceRows; 
      } 
     } 

     private void UpdateStatuses() 
     { 
      int original = 0, added = 0, todelete = 0, edited = 0; 
      foreach (SpecialPriceRow SPR in SpecialPriceRows) 
      { 
       switch (SPR.Status) 
       { 
        case SpecialPriceRow.ChangeStatus.Original: 
         original++; 
         break; 
        case SpecialPriceRow.ChangeStatus.Added: 
         added++; 
         break; 
        case SpecialPriceRow.ChangeStatus.ToDelete: 
         todelete++; 
         break; 
        case SpecialPriceRow.ChangeStatus.Edited: 
         edited++; 
         break; 
        default: 
         break; 
       } 
      } 
      Original = original; 
      Added = added; 
      ToDelete = todelete; 
      Edited = edited; 
     } 

     public int Original 
     { 
      get 
      { 
       return _Original; 
      } 
      set 
      { 
       _Original = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("Original")); 
      } 
     } 

     public int Added 
     { 
      get 
      { 
       return _Added; 
      } 
      set 
      { 
       _Added = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("Added")); 
      } 
     } 

     public int ToDelete 
     { 
      get 
      { 
       return _ToDelete; 
      } 
      set 
      { 
       _ToDelete = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("ToDelete")); 
      } 
     } 

     public int Edited 
     { 
      get 
      { 
       return _Edited; 
      } 
      set 
      { 
       _Edited = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("Edited")); 
      } 
     } 
    } 

注意构造函数中的注释。您需要将每个SpecialPriceRow的PropertyChanged事件指向UpdateStatuses函数,以使其正常工作。 现在您只需将标签绑定到ViewModel中的相应属性即可。 如果您的SpecialPriceRows列表变得非常大,您可能需要考虑计算状态计数有点不同。目前,每次更新一个实例时都会遍历整个列表。为了更好地执行此操作,您可能需要将状态的旧值保留在SpecialPriceRow类中,并且每次发生更新时,都会增加新的状态计数并减少旧的值。