You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选Observable Collection中属性匹配指定条件的项?—— Hymn集合按HymnType Title筛选后返回Null问题排查

问题原因与解决方案

你的筛选后列表返回Null的核心问题在于LINQ的Where方法返回的是IEnumerable<Hymn>类型,而非ObservableCollection<Hymn>。当你用as ObservableCollection<Hymn>进行类型转换时,因为两种类型不兼容,转换失败,结果就变成了Null——这就是问题的根源。

解决方法1:将筛选结果重新包装为ObservableCollection

直接把Where返回的IEnumerable<Hymn>传入ObservableCollection的构造函数,创建一个新的集合实例:

public class HymnTypeContentPageViewModel : BaseViewModel { 
    ObservableCollection<Hymn> _hymns; 
    public ObservableCollection<Hymn> Hymns { get => _hymns; set => SetProperty(ref _hymns, value); } 
    public HymnTypeContentPageViewModel(HymnType hymnType) { 
        string keyword = hymnType.Title.ToLower(); 
        // 先初始化原始集合
        var initialHymns = new ObservableCollection<Hymn> { 
            new Hymn { HymnNumber = 201, Title = "All Things Bright and Beautiful", HymnTypeName = StaticStrings.AncientAndModern, Body = "Test Body Ancient and Modern" }, 
            new Hymn { HymnNumber = 270, Title = "He Arose", HymnTypeName = StaticStrings.SomeOtherHymns, Body = "Test Body Some Other Hymn" }, 
        }; 
        // 将筛选后的IEnumerable转为ObservableCollection
        Hymns = new ObservableCollection<Hymn>(initialHymns.Where(h => h.HymnTypeName.ToLower().Contains(keyword))); 
    } 
}

解决方法2:保留原集合引用(适合绑定场景)

如果你的UI已经绑定了Hymns集合,不想重新创建实例,可以先清空原集合,再添加筛选后的项:

public class HymnTypeContentPageViewModel : BaseViewModel { 
    ObservableCollection<Hymn> _hymns; 
    public ObservableCollection<Hymn> Hymns { get => _hymns; set => SetProperty(ref _hymns, value); } 
    public HymnTypeContentPageViewModel(HymnType hymnType) { 
        string keyword = hymnType.Title.ToLower(); 
        Hymns = new ObservableCollection<Hymn> { 
            new Hymn { HymnNumber = 201, Title = "All Things Bright and Beautiful", HymnTypeName = StaticStrings.AncientAndModern, Body = "Test Body Ancient and Modern" }, 
            new Hymn { HymnNumber = 270, Title = "He Arose", HymnTypeName = StaticStrings.SomeOtherHymns, Body = "Test Body Some Other Hymn" }, 
        }; 
        // 先获取筛选结果,再更新原集合
        var filteredHymns = Hymns.Where(h => h.HymnTypeName.ToLower().Contains(keyword)).ToList();
        Hymns.Clear();
        foreach (var hymn in filteredHymns)
        {
            Hymns.Add(hymn);
        }
    } 
}

优化建议:避免不必要的ToLower调用

为了提高效率并避免文化差异带来的问题,可以用StringComparison.OrdinalIgnoreCase替代ToLower()进行不区分大小写的匹配:

// 替代ToLower的写法
Hymns = new ObservableCollection<Hymn>(initialHymns.Where(h => 
    h.HymnTypeName.Contains(keyword, StringComparison.OrdinalIgnoreCase)));

内容的提问来源于stack exchange,提问作者Orukele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:19:05