【发布时间】:2020-03-21 01:22:30
【问题描述】:
我正在尝试创建一个 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));
}
}
我的目标是让ConflictLayers 成为仅TargetDrawingLayers 内LayerModels 的集合,其中 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;
}
}
我做错了什么?
【问题讨论】:
-
Linq 方法 Intersect 可能会对您有所帮助。确保在要比较的类上实现 IEquatable
-
ConflictLayers = TargetDrawingLayers.Except(SourceDrawingLayers) -
ConflictLayers = TargetDrawingLayers.Except(SourceDrawingLayers).Union(SourceDrawingLayers.Except(TargetDrawingLayers)
-
我尝试了 reggaeguitar 和 Robert McKee 的建议,但没有得到很好的结果。我已经用详细信息编辑了我的问题。
-
您是否也覆盖了 GetHashCode?这可能是问题
标签: c# wpf linq observablecollection