通过使用LINQ和MVVM过滤两个相同类型的ObservableCollection来创建ObservableCollection

我正在尝试创建ObserverableCollection,以通过查看其他集合并添加目标集合中与源集合具有不同值的任何对象来填充网格视图。

我有一个模特:

public class LayerModel
{
    public string Name { get; set; }

    public string OnOff { get; set; }

    public string Freeze { get; set; }

    public string Color { get; set; }

    public string Linetype { get; set; }

    public string Lineweight { get; set; }

    public string Transparency { get; set; }

    public string Plot { get; set; }
}

以及我的视图模型中该模型的两个ObservableCollections:

public ObservableCollection<LayerModel> SourceDrawingLayers { get; set; }

public ObservableCollection<LayerModel> TargetDrawingLayers { get; set; }

冲突集合:

public ObservableCollection<LayerModel> ConflictLayers {get; set;}

最后,要与之进行比较的目标图纸集合:

ObservableCollection<TargetDrawingModel> TargetDrawings {get; set;}

在应用程序中,要求用户选择源图形。提示用户输入OpenFileDialog并选择图形文件。此时,SourceDrawingLayers是通过一种方法来创建的,该方法查看该文件中的每一层并创建集合。

接下来,用户必须选择一组目标工程图,以TargetDrawingModel表示。所选内容已添加到TargetDrawings

现在有趣的部分。

我需要打开每个目标图形并读取图层,然后将这些图层与SourceDrawingLayers进行比较,如果属性不同,则需要将其添加到ConflictLayers

到目前为止,我已经尝试了一个讨厌的三层嵌套的foreach语句,该语句无法正常运行,所以我开始研究LINQ,因为似乎可以轻松解决我的问题,但结果却很奇怪。

这是我目前所在的位置。我试图使用“ where”语句仅查看我的LayerModel内部的OnOff属性,但是生成的ConflictLayers ObservableCollection只是填充了TargetDrawing内部的每一层并按原样显示其设置。

    private void PopulateConflictLayers()
    {
        foreach (TargetDrawingModel targetDrawingModel in TargetDrawings)
        {
            Dataaccess da = new Dataaccess();
            TargetDrawingLayers = da.GetDrawingLayers(targetDrawingModel.DrawingPath);
            ConflictLayers = TargetDrawingLayers.Where(y => SourceDrawingLayers.Any(z => z.OnOff == y.OnOff));
        }
    }

我的目标是让ConflictLayersLayerModelTargetDrawingLayers only 的集合,其中 any 属性可以与SourceDrawingLayers中的内容不匹配。

我也尝试使用Any方法,但是得到了完全相同的结果,我的ConflictLayers只是对目标图形中的每个LayerModel进行了显示,而不管其设置或是否匹配SourceDrawingLayers内的任何内容。

任何想法都会得到极大的赞赏

更新:我尝试了下面由reggaeguitar提供的解决方案,结果是我的数据网格只显示了我添加到集合中的源图形和目标图形中的所有层,而没有过滤。

我在LayerModel上实现了IEquatable

 public bool Equals(LayerModel other)
    {
        if (other == null)
            return false;
        return
        Name == other.Name
        && OnOff == other.OnOff
        && Freeze == other.Freeze
        && Color == other.Color
        && Linetype == other.Linetype
        && Lineweight == other.Lineweight
        && Transparency == other.Transparency
        && Plot == other.Plot;
    }

并更新了我的方法,如下所示:

 private void PopulateConflictLayers()
    {
        foreach (TargetDrawingModel targetDrawingModel in TargetDrawings)
        {
            Dataaccess da = new Dataaccess();
            TargetDrawingLayers = da.GetDrawingLayers(targetDrawingModel.DrawingPath);
            var s = TargetDrawingLayers.Except(SourceDrawingLayers).Union(SourceDrawingLayers.Except(TargetDrawingLayers));
            ObservableCollection<LayerModel> list = new ObservableCollection<LayerModel>(s);
            ConflictLayers = list;
        }
    }

我做错了什么?

as97100590 回答:通过使用LINQ和MVVM过滤两个相同类型的ObservableCollection来创建ObservableCollection

我找到了要发布的解决方案。

我最终修改了我的代码,

ConflictLayers = TargetDrawingLayers.Where(i => !SourceDrawingLayers.Contains(i)).ToList();

我还在IEquatable上实现了LayerModel,并在其上覆盖了GetHashCode()。结果是我的ConflictLayers现在正确地填充了LayerModels,其属性不同于SourceDrawing

本文链接:https://www.f2er.com/3034523.html

大家都在问