使用DynamicData合并SourceList,如何保持新增元素的原列表顺序?
解决SourceList拼接后新增元素位置错误的问题
你用Or拼接多个SourceList的变更流时,新增元素会跑到合并列表的末尾,而非留在原列表的对应位置。这是因为Or本质是合并各列表的增量变更事件,直接把每个变更操作应用到结果集合,不会维护原列表的层级顺序结构。
解决方案
不要依赖增量变更合并,而是在任意列表发生变化时,重新全量构建合并后的列表。通过监听所有列表的变更事件,每次触发时按list1 → list2 → list3的固定顺序拼接全部元素,再同步到结果集合。
修改后的完整代码
var list1 = new SourceList<string>(); list1.AddRange(new[] { "list1 value 1", "list1 value 2", "list1 value 3" }); var list2 = new SourceList<string>(); list2.AddRange(new[] { "list2 value 1", "list2 value 2", "list2 value 3" }); var list3 = new SourceList<string>(); list3.AddRange(new[] { "list3 value 1", "list3 value 2", "list3 value 3" }); // 替换原合并逻辑 var combineOperation = Observable.Merge(list1.Connect(), list2.Connect(), list3.Connect()) .Select(_ => list1.Items.Concat(list2.Items).Concat(list3.Items).ToList()) .Bind(out var combineResult) .Subscribe(); Debug.WriteLine(string.Join("\n", combineResult)); list1.Add("list1 value 4"); Debug.WriteLine(""); Debug.WriteLine(string.Join("\n", combineResult)); combineOperation.Dispose();
代码说明
Observable.Merge:同时监听三个列表的所有变更事件(添加、删除、修改)Select:每次有变更时,重新按固定顺序拼接三个列表的全部元素,生成完整的新列表Bind:将新列表同步到combineResult,确保合并后的顺序始终是list1在前,接着list2,最后list3
运行这段代码后,新增的list1 value 4会出现在list1原有元素的后方,完全符合你的期望输出。这种全量构建的方式虽然会多一些计算,但能严格保证你需要的顺序结构,也解决了排序后合并丢失顺序的问题——每次都是基于最新的原列表状态重新拼接,不会依赖增量变更的顺序。
内容的提问来源于stack exchange,提问作者ManIkWeet
相关产品推荐
相关产品推荐

