当 ObservableCollection 更改时重新评估 LINQ 查询

2024-07-04

我有一个常见问题,我希望(希望)找到更好的解决方案来继续前进。我有一个包含数据主列表的 ObservableCollection。在我的客户端代码中,我需要将数据“转换”为新的形式以显示给用户。我使用如下 LINQ 语句:

var newList = (from item in observable
               select new { FirstInitial = item.Name[0] });

我知道这很初级,但足以证明问题。 (请注意投影,这不是一个简单的过滤器或分组语句。)然后,我通过数据绑定在 UI 中显示 newList。

问题是,当原始集合发生变化时,用户界面却没有变化。到目前为止,我应用的解决方案是将一个事件处理程序附加到原始集合的 CollectionChanged 事件,该事件重新评估查询并更新绑定属性。

虽然这工作得很好,但每次我遇到这个场景时都会有很多重复的代码。有没有一种方法可以让 LINQ 查询返回一个 ObservableCollection,当源 Observable 更改时,该集合会“自动”更新?

换句话说,我想实现一些“固定”功能,这样每当遇到这种情况时我就可以简单地重用它。

UPDATE

感谢 Scroog1 帮助我发现我原来的帖子与 UI 的耦合度太高,无法满足我真正的要求。下面的例子可以更好地描述问题:

public class SomeClass
{
    private ObservableCollection<Employee> _allEmployees;
    private ObservableCollection<Employee> _currentEmployees;

    public ObservableCollection<Employee> CurrentEmployees
    {
        get
        {
            if (_currentEmployees == null)
                _currentEmployees = _allEmployees.Where(e => !e.IsTerminated);

            return _currentEmployees;
        }
    }
}

public class SomeViewModel
{
    private ICollectionView _view;

    public ICollectionView CurrentView
    {
        if (_view == null)
        {
            var cvs = new CollectionViewSource()
            {
                Source = someClass.CurrentEmployees
            }

            cvs.Add(new SortDescription("Name", ListSortDirection.Ascending));

            _view = cvs.View;
        }

        return _view;
    }
}

正如您所看到的,查询所在的代码并不是直接绑定到 UI 的代码。我使用此示例来证明我是从更一般的用例中提出请求,而不是严格的 UI 数据绑定场景。


我会做这样的事情(假设一个名为 observable 的 ObservableCollection 和使用 RaisePropertyChanged 方法实现 INotifyPropertyChanged 的​​类):

public IEnumerable<string> NewList
{
    return from item in observable
           select item.Name;
}

observable.CollectionChanged += delegate { RaisePropertyChanged("NewList"); };

然后,当 observable 更改时,UI 将被告知 NewList 已更改并重新评估查询。

对于多个从属项目,您可以执行以下操作:

observable.CollectionChanged += delegate
    {
        RaisePropertyChanged("NewList",
                             "OtherProperty",
                             "YetAnotherProperty",
                             "Etc");
    };

Update

上面的方法通常对于属性来说效果很好,因为每次访问它时您都会获得最新的值,并且 INPC 可用于告诉事物重新读取它。

对于稍微更有趣的集合案例,我将实现一个自定义类,该类实现 INotifyCollectionChanged 和 IEnumerable 并包装 LINQ。例如。,

public class CustomObservableCollection<T> : INotifyCollectionChanged,
                                             INotifyPropertyChanged,
                                             IEnumerable<T>
{
    private readonly IEnumerable<T> _collection;
    public CustomObservableCollection(IEnumerable<T> collection)
    {
        _collection = collection;
    }
    public IEnumerator<T> GetEnumerator()
    {
        _collection.GetEnumerator();
    }
    public void RaiseCollectionChanged() { ... }
    ...
}

然后你可以这样做:

var newList = new CustomObservableCollection(from item in observable
                                             select item.Name);
observable.CollectionChanged += delegate { newList.RaiseCollectionChanged(); };

Update 2

您甚至可以将依赖项传递给 Custom ObservableCollection:

public class CustomObservableCollection<T> : INotifyCollectionChanged,
                                             INotifyPropertyChanged,
                                             IEnumerable<T>
{
    private readonly IEnumerable<T> _collection;
    public CustomObservableCollection(IEnumerable<T> collection,
                 params ObservableCollection[] dependencies)
    {
        _collection = collection;
        foreach (var dep in dependencies)
            dep.CollectionChanged += RaiseCollectionChanged();
    }
    public IEnumerator<T> GetEnumerator()
    {
        _collection.GetEnumerator();
    }
    public void RaiseCollectionChanged() { ... }
    ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当 ObservableCollection 更改时重新评估 LINQ 查询 的相关文章

  • .NET 元组和等于性能

    这是我直到今天才注意到的事情 显然 常用的元组类的 NET 实现 Tuple
  • HttpUtility.HtmlDecode 不解码空格?

    我有这个 string test HttpUtility HtmlDecode http test com Folder1 Folder2 my 20view aspx 当我查看测试时 它仍然有 20 而不是空格 为什么它不解码这个 您正在
  • 小数可以表示的第二个最小值是多少?

    什么是第二个最小值值一个decimal可以代表吗 该值大于Decimal MinValue并且小于任何其他值decimal可以代表 在C 中如何获取这个值 谢谢 第二个最小值是Decimal MinValue 1 这可以从文档中推断出dec
  • 使用 Json.NET 将任何类型的对象转换为 JObject

    我经常需要使用附加信息扩展我的域模型 然后再使用 WebAPI 将其返回给客户端 为了避免创建 ViewModel 我认为可以返回带有附加属性的 JObject 然而 我无法找到通过单次调用 Newtonsoft JSON 库将任何类型的对
  • 在编写任何锁之前我应该​​对多线程问题进行单元测试吗?

    我正在编写一个我知道需要锁的类 因为该类必须是线程安全的 但由于我是测试驱动开发 我知道在为其创建测试之前我无法编写一行代码 我发现很难做到 因为测试最终会变得非常复杂 在这些情况下你通常会做什么 有什么工具可以帮助解决这个问题吗 这个问题
  • PublicKeyToken=null 时会忽略程序集绑定吗?

    我的中有以下内容app config
  • 调用存储过程、传递 NULL 值、处理布尔值

    调用存储过程时 我将值连接在一起 我的问题是如何调用存储过程但在其中一个参数中发送 NULL 值 假设 AID null 但如果我将其传递给我的查询 我会收到错误 QueryConn Execute Search Res Count Acc
  • .net 新进程沙箱用于不受信任的代码

    所以我需要在新进程中运行动态编译的不受信任的代码 我找到了如何在新的 AppDomain http msdn microsoft com en us library bb763046 aspx 中执行此操作 但没有在新进程中执行此操作 可以
  • List 的 linq 查询语法

    我正在尝试做这样的事情 public static List
  • 远程控制内网机器上安装的windows服务

    我在本地 IIS 7 上部署了 Web 应用程序 并将应用程序池配置为在内置 NETWORK SERVICE 帐户下工作 我需要从这个 Web 应用程序检查 Windows 服务的状态 是否已启动 已停止等 我用这样的语句来得到它 publ
  • FindByIdentity - 性能差异

    以下代码在我们域中的各种机器上运行良好 var context new PrincipalContext ContextType Domain var principal UserPrincipal FindByIdentity conte
  • 使用 WebClient 下载时获取原始文件名

    当 Uri 不包含名称时 有什么方法可以知道使用 WebClient 下载的文件的原始名称吗 例如 在下载源自预先未知名称的动态页面的网站中 就会发生这种情况 使用我的浏览器 该文件获得正确的名称 但是如何使用 WebClient 来完成此
  • 计算字符串中某个字符出现的次数? [复制]

    这个问题在这里已经有答案了 可能的重复 计算字符串中特定字符的出现次数 https stackoverflow com questions 5193893 count specific character occurances in str
  • 使用 LINQ 的 IQueryable 左外连接的扩展方法

    我正在尝试使用返回类型实现左外连接扩展方法IQueryable 我写的函数如下 public static IQueryable
  • C# 2.0中使用HashSet,兼容3.5

    我真的很想在我的程序中使用哈希集 使用字典感觉很丑 有一天我可能会开始使用 VS2008 和 Net 3 5 所以我的理想是即使我不能 或者我可以 使用hashsets http msdn microsoft com en us libra
  • 如何在C#中隐藏文件?

    我想在c 中隐藏一个文件 我知道文件路径并且可以创建 FileInfo 对象 我怎样才能隐藏它 之前接受的答案 File SetAttributes path FileAttributes Hidden 将导致它可能丢失某些其他属性 因此您
  • 我如何解决 log4net 不断更改 publickeytoken 的问题

    我们有一个 asp net 4 0 项目 它使用几个依赖于 log4net 版本 1 2 10 0 的框架 今天我尝试包含一个依赖于 log4net 版本 1 2 11 0 的新框架 从那时起我就陷入困境 log4net 1 2 10 0
  • 如何使文本框的自动完成列表可编辑?

    我有一个包含很多内容的应用程序TextBox使用自动完成的控件 每个人都使用AutoCompleteMode CustomSource从关联的获取自动完成文本AutoCompleteStringCollection 每当用户在其中输入新值时
  • 如何使用 Linq 对通用集合进行分页?

    我有一个 System Generic Collections List Of MyCustomClass 类型对象 给定整数变量 pagesize 和 pagenumber 如何仅查询 MyCustomClass 对象的任何单个页面 如果
  • 国际象棋棋步验证库[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 NET 中是否有可用于验证国际象棋走法和模拟游戏的库 如果该库能够理解代数符号中的移动并提供简单的 A

随机推荐