比较两个ObservableCollection(s),看它们是否不同
本文关键字:是否 两个 ObservableCollection 比较 | 更新日期: 2023-09-27 18:19:21
我正在比较listview的两个版本,用于设置表单。我需要知道用户是否真的修改了列表,在这种情况下,当他们点击"保存"时,我就会保存。如果他们没有更改任何内容,当他们点击"保存"时,我就不会浪费内存/时间重新保存他们没有更改的内容。
无论如何,我如何比较两个observablecollection来查看它们是否完全不同?
提前感谢!
您可以使用LINQ Except方法:生成两个序列的集合差。
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except.aspx考虑下面的示例方法…
public void ExceptFunctioni()
{
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };
IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);
if(aOnlyNumbers.Count()>0)
{
// do something
}
}
在第一个集合上调用Except方法,并将第二个集合作为参数传递。结果将包含差异。然后,您可以查询结果并采取相应的操作。如果两个序列相等,则结果计数为0。
话虽如此,值得注意的是,在MVVM世界中,首选策略是使用此方法来控制是否启用"保存"按钮。在这种方法中,如果两个集合相等,"Save"按钮将被禁用,用户无法访问它。
但无论哪种方式,LINQ方法都提供了一种非常简洁的方式来实现你所追求的…
补充:看到你在回复'Dumb'的评论中所做的评论,你的'oldList'将对应于上面示例代码中的numbersB…
还有来自'Stonetip'的评论(感谢他)…
More succinct: if(numbersA.Except(numbersB).Any()) { // do something }
我们处理这个问题的方式需要预先多做一点工作,但它可以使用VS宏或代码生成工具(如codessmith)自动完成。
但是,这种方法可以扩展到集合绑定到的任何UI构造,并且不必在每次需要知道是否有更改时都在UI中重新实现。
这个概念是更新集合和业务对象中的标志,以确定集合成员是否已更改,或者集合内的任何给定记录是否已更改。
实现相当简单:
为业务对象类添加一个HasChanged属性。
向集合添加AnyDeleted属性。只有当项从集合中删除时才会设置。
在从DB读取记录后将这些值初始化为false。
(现在是半乏味的部分)对于类中的每个属性,如果值实际发生变化,则将HasChanged属性设置为true。注意空值。例如:
public bool IsSelected
{
get
{
return m_fIsSelected;
}
set
{
if (m_fIsSelected != value)
{
this.HasChanged = true;
m_fIsSelected = value;
}
}
}
修改集合,在删除记录时将AnyDeleted属性设置为true:
protected override void RemoveItem(int index)
{
this.AnyDeleted = true;
base.RemoveItem(index);
}
最后,向集合添加一个方法,以指示是否有任何更改。您将调用这个方法来确定是否需要保存任何更改:
public bool HasAnyChanges()
{
// Exceptions are handled by the caller
// If anything was deleted, return true
if (this.AnyDeleted)
{
return true;
}
else
{
foreach (T theItem in this)
{
if (theItem.HasAnyChanges())
{
return true;
}
}
}
return false;
}
我认为,你关注的方法是错误的。您不应该比较绑定到ListView
的两个列表的内容,因为它们包含的项目数量可能非常大。
-
最好是专注于定义一个单一的(如果可能的话)和统一的方式来从API改变集合的内容,为你的类消费者提供一个通用的方式来改变集合中的一些东西。如果使用该方法,则可以保存一个布尔值
flag
,该值标识是否发生了更改。 -
或者你可以假设,如果有人在绑定的集合属性中使用
set
方法,意味着集合被改变了。
换句话说,传递应用程序的预定义工作流,或者定义用于更改内容的API
,这样您就能够在更改集合的内容时确定,如果更改则确定。
和另一个概念:没有意义让用户点击Save
和不保存。如果可以单击Save
,则必须执行用户请求的命令。如果你担心性能(你不想保存一些东西,如果它没有从上次保存更改),那么禁用Save
按钮,如果保存不合适。换句话说,让UI
填充并按照应用程序的预期行事。让用户清楚应用程序现在做什么,不做什么。