2013-07-01 150 views
0

我有一個可觀察的實體集合,每個實體都添加,刪除,修改和取消了一個狀態。根據過濾規則過濾集合

我點擊時應該過濾我的收藏如下四個按鈕(切換):

  • 如果我選擇按鈕。接着,添加我的收藏應該包含實體狀態添加。
  • 如果我選擇刪除和​​添加按鈕,那麼我的收藏應該包含狀態爲已刪除且實體狀態爲已添加的實體,其餘都不包含。
  • 如果我選擇刪除,添加和修改按鈕,那麼我的收藏應該包含狀態爲已刪除,已添加和已修改的實體。 。 。等等。
  • 如果我取消選擇其中一個按鈕,它應該從具有該狀態的集合中刪除這些實體。例如,如果我取消選中「已刪除」,但選擇「已添加和已修改」,則我的收藏夾應包含具有「已添加」和「已修改」狀態且未刪除的項目。

爲了實現這一點,我創建了一個主集合和一個過濾的集合。 Filter集合根據選擇和取消選擇進行篩選。以下是我的代碼:

private bool _clickedAdded; 
    public bool ClickedAdded 
    { 
     get { return _clickedAdded; } 
     set 
     { 
      _clickedAdded = value; 
      if(!_clickedAdded) 
       FilterAny(typeof(Added)); 

     } 
    } 

    private bool _clickedDeleted; 
    public bool ClickedDeleted 
    { 
     get { return _clickedDeleted; } 
     set 
     { 
      _clickedDeleted = value; 
      if (!_clickedDeleted) 
       FilterAny(typeof(Deleted)); 
     } 
    } 

    private bool _clickedModified; 
    public bool ClickedModified 
    { 
     get { return _clickedModified; } 
     set 
     { 
      _clickedModified = value; 
      if (!_clickedModified) 
       FilterAny(typeof(Modified)); 
     } 
    } 

    private void FilterAny(Type status) 
    { 
     Func<Entity, bool> predicate = entity => entity.Status.GetType() != status; 

     var filteredItems = MasterEntites.Where(predicate); 
     FilteredEntities = new ObservableCollection<Entity>(filteredItems); 
    } 

然而,這打破了上述規則 - 例如,如果我已經全部選中,然後我刪除,隨後加入刪除,則它仍然顯示新增的名單,修改和取消。它應該只是在已過濾的集合中進行了修改和取消。

你能幫我解決這個問題嗎?我也需要2個不同的列表來解決這個問題。請注意我正在使用.NET 3.5。

+0

我的假設是,你是不是讓你的謂詞對你以前的過濾。你可以添加Filter方法的代碼嗎?另外我假設ClickedCancelled看起來與其他Click *方法相同? – Kevin

+0

是的,點擊Cancelled是一樣的。過濾器代碼是FilterAny方法中的一個。 – Mike

+0

**過濾器(typeof運算(刪除)); **不調用該方法**私人無效FilterAny(類型狀態)**您可以加入,做的代碼。 – Kevin

回答

1

你需要Linq的擴展 - http://www.albahari.com/nutshell/predicatebuilder.aspx 這個類提供了PredicateBuilder,它可以在運行中創建查詢。

using System; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Collections.Generic; 

public static class PredicateBuilder 
{ 
    public static Expression<Func<T, bool>> True<T>() { return f => true; } 
    public static Expression<Func<T, bool>> False<T>() { return f => false; } 

    public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1, 
                 Expression<Func<T, bool>> expr2) 
    { 
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression>()); 
    return Expression.Lambda<Func<T, bool>> 
      (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters); 
    } 

    public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1, 
                 Expression<Func<T, bool>> expr2) 
    { 
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression>()); 
    return Expression.Lambda<Func<T, bool>> 
      (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters); 
    } 
} 

然後你做一個onclick處理所有這些按鈕和裏面你把下面的代碼

var predicate = PredicateBuilder.False<Entity>(); 

    if(ClickedAdded) 
     predicate = predicate.Or(x=>x.Status == "Added"); 
    if(ClickedDeleted) 
     predicate = predicate.Or(x=>x.Status == "Deleted"); 
    if(ClickedModified) 
     predicate = predicate.Or(x=>x.Status == "Modified"); 

    return masterEntities.AsQueryable().Where(predicate); 
+0

C#的字符串格式使用'''而不是'''。好的忍者編輯。 –

+0

謝謝你的要點。 我做了這些更改,因爲我錯過了 - 或 - 當第一次閱讀這篇文章時:( –

+0

不錯,名稱@newStackExchangeInstance –