2013-07-01 59 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 –