C# WPF 比较列表 <T> 到 Datagrid.ItemsSource

C# WPF compare List<T> to Datagrid.ItemsSource

我将 private List<MaintenanceWindow> tempMaintenanceWindows 绑定到 Datagrid 并使用户能够编辑 Datagrid 中的项目以及添加新项目。这很好用。

现在我想到了如果 window 没有先按保存按钮就关闭了,如何回滚用户所做的更改。基本上,我想将 Datagrid.ItemsSource 与我填充的临时列表进行比较:

foreach (MaintenanceWindow mainWin in maintenanceWindowList)
                tempMaintenanceWindows.Add(new MaintenanceWindow {from = mainWin.from, to = mainWin.to, abbreviation = mainWin.abbreviation, description = mainWin.description, hosts = mainWin.hosts });

我是这样比较两者的:

if (!tempMaintenanceWindows.SequenceEqual((List<MaintenanceWindow>)mainWinList.ItemsSource))

但 SequenceEqual 的结果似乎总是错误的,尽管在调试代码时,它们似乎是完全相同的东西。

希望有人能提供帮助。谢谢。


Quentin Roger 提供了一种有效的方法解决方案,但我想 post 我的代码,这可能不是最简洁的方法,但它适合我的应用程序。

这就是我覆盖 MaintenanceWindow 对象的 Equals 方法的方式:

public override bool Equals (object obj)
        {
            MaintenanceWindow item = obj as MaintenanceWindow;

            if (!item.from.Equals(this.from))
                return false;
            if (!item.to.Equals(this.to))
                return false;
            if (!item.description.Equals(this.description))
                return false;
            if (!item.abbreviation.Equals(this.abbreviation))
                return false;
            if (item.hosts != null)
            {
                if (!item.hosts.Equals(this.hosts))
                    return false;
            }
            else
            {
                if (this.hosts != null)
                    return false;
            }

            return true;
        }

默认SequenceEqual会比较调用equal函数的每一项,你重写equal了吗?否则它比较 class.

的内存地址

另外,我鼓励您在寻找不可变列表比较时使用 FSharpList

"So in the override method do I have to compare every single field of my MaintenanceWindow class"

你必须比较每个有意义的字段,是的。

如果您这样声明维护窗口:

正如我在评论中所说,你必须比较每个重要的 fields.In 我选择描述的以下实现,因此如果两个 MaintenanceWindow 得到相同的 description 它们将被视为相等并且 SequenceEquals 会按预期工作。

 internal class MaintenanceWindow
 {
    public object @from { get; set; }
    public object to { get; set; }
    public object abbreviation { get; set; }

    private readonly string _description;
    public string Description => _description;

    public MaintenanceWindow(string description)
    {
        _description = description;
    }

    public string hosts { get; set; }

    public override bool Equals(object obj)
    {
        return this.Equals((MaintenanceWindow)obj);
    }

    protected bool Equals(MaintenanceWindow other)
    {
        return string.Equals(_description, other._description);
    }

    public override int GetHashCode()
    {
        return _description?.GetHashCode() ?? 0;
    }
}