我正在比較設置表單的兩個版本的listview。我需要知道用戶是否真的修改了列表,在這種情況下,當他們點擊「保存」時,我將實際保存。如果他們沒有改變任何東西,當他們點擊「保存」時,我不會浪費記憶/時間重新保存他們沒有改變的東西。比較兩個ObservableCollection(s)以查看它們是否不同
無論如何,我怎麼能比較兩個ObservableCollections,看看他們是否有所不同?
在此先感謝!
我正在比較設置表單的兩個版本的listview。我需要知道用戶是否真的修改了列表,在這種情況下,當他們點擊「保存」時,我將實際保存。如果他們沒有改變任何東西,當他們點擊「保存」時,我不會浪費記憶/時間重新保存他們沒有改變的東西。比較兩個ObservableCollection(s)以查看它們是否不同
無論如何,我怎麼能比較兩個ObservableCollections,看看他們是否有所不同?
在此先感謝!
我們處理這個問題的方式需要多一點工作,但可以使用VS宏或代碼生成工具(如CodeSmith)自動執行。
但是,這種方法可以擴展到集合綁定到的任何UI構造,並且在每次需要知道是否存在更改時都不必在UI中重新實現。
該概念用於更新集合和業務對象內的標誌,以確定集合成員資格是否已更改或集合中的任何給定記錄是否已更改。
實現相當簡單:
一個HasChanged屬性添加到業務對象類。
將AnyDeleted屬性添加到集合中。只有在項目從集合中刪除時纔會設置。
從數據庫中讀取記錄後,將這些值初始化爲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;
}
編輯:
void ListView_ItemInserted(Object sender, ListViewInsertedEventArgs e)
{
if (e.Exception == null)
{
if (e.AffectedRows > 0)
{
flag = True;
}
else
{
flag = False;
}
}
void ListView_Itemdeleted(Object sender, ListViewDeletedEventArgs e)
{
if (e.Exception == null)
{
if (e.AffectedRows > 0)
{
flag = True;
}
else
{
flag = False;
}
}
void ListView_ItemUpdated(Object sender, ListViewUpdatedEventArgs e)
{
if (e.Exception == null)
{
if (e.AffectedRows > 0)
{
flag = True;
}
else
{
flag = False;
}
}
可以在保存前檢查此標誌變量。這會做!如果它是真的,保存它!
您可以使用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
}
}
的除方法被調用在所述第一收集和通過了第二集合作爲參數。結果將包含差異。然後,您可以查詢結果並相應採取行動。如果兩個序列相等,則結果的計數將爲零。
話雖如此,值得一提的是,MVVM世界中的首選策略是使用此方法來控制是否啓用「保存」按鈕。在這種方法中,如果兩個集合相同,則「保存」按鈕將被禁用,用戶將無法訪問它。
但無論哪種方式,LINQ方法提供實現你追求的一個很濃縮的方式...
補充說:看到你在回答「啞的」意見所提出的意見,你的「oldList」會對應於在numbersB上面的示例代碼...
另外,從comment '3210'(對誰感謝)...
More succinct: if(numbersA.Except(numbersB).Any()) { // do something }
我認爲這些詞很容易混淆,並且「oldList僅僅是舊列表(用戶改變它們之前的當前設置)」意味着他可能會說已經保存到設置中,而當前列表意味着不保存。他可能沒有兩個集合,但已經保存了一個(他將它虛擬成一個集合),另一個集合在列表視圖上。如果他在內存中同時擁有兩個集合,那麼除了LINQ的方法之外,它還是很好用的。使用LINQ(簡明方法)+1。讓我們聽聽他關於他作品的更多描述。 – King 2012-01-01 14:59:50
@啞,嗨,新年快樂!您是否可以使用'編輯'功能來修改令人困惑的部分,以便清楚?你是否意味着這些設置並不意味着持久? – 2012-01-01 15:10:06
新年快樂!我正在等待他澄清一點,以便我們能夠確切瞭解他需要什麼,並且我們可以編輯這些內容。是。我認爲他的數據不是持久的。但是,當然有兩個版本與他在評論中所說的內容不一致。所以他希望每次使用listview檢查時都檢查一下,這就是爲什麼我建議檢查listview方法的事件。但是如果他有兩個版本的持久數據,我會推薦使用你的方法! – King 2012-01-01 15:27:54
我個墨水,你正在關注錯誤的方法。您不應該將綁定到ListView
的2個列表的內容進行比較,因爲它們包含的項目數量可能過大。
這是更好地專注於制定一個統一(這是可能的)和統一的方式能夠改變的集合來自API的內容,提供給您的消費階層的一般方法,以能夠改變收藏中的東西。如果使用該方法,您可以保存一個布爾值flag
,用於標識是否更改了某些內容。
或者你可以假設,如果有人在綁定收集屬性中使用set
方法,意味着集合已被更改。
換句話說,繼電器或您的應用程序的預定義的工作流程,或改變內容的定義API
,這樣你就可以找出當和如果集合的內容被改變。
還有一個概念:沒有意義讓用戶點擊Save
和不保存。如果可以點擊Save
,則必須執行用戶請求的命令。如果您對性能保持警惕(如果不想保存某些內容,如果不是上次保存的更改),請在保存不合適的情況下禁用Save
按鈕。換句話說,使用UI
填充並按照您的應用程序的預期運行。讓用戶清楚現在應該做什麼以及不做什麼。
沒有兩個列表視圖,實際上只有一個。 – mattsven 2012-01-01 00:26:12
你的問題表明有兩個版本的listviews! 那麼你的意思是?你再次提到過比較兩個! – King 2012-01-01 00:31:29
你正在綁定一個像XML一樣的數據結構或將它作爲字符串,然後將其保存在設置?是這樣嗎 ? @NeXXeuS如果我理解你的問題是這樣的。然後,除非應用程序具有內存中的設置並不斷更新它,否則您必須閱讀設置並執行此操作。它和拯救它一樣。如果事實如此,我認爲它不會在性能方面產生影響。 – King 2012-01-01 00:37:39