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;
}
}
我将 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;
}
}