2014-03-19 42 views
3

可以說我有一個ObservableCollection WPF應用程序中的ViewModel。此集合與Model集合同步,以便更新其中一個更新另一個。該模型有一條業務規則,規定它必須始終包含2件事情,但集合中的順序可以更改。用戶將看到一個列表,其中有兩件事情,並有按鈕,他們可以點擊來移動一件事。模型類訂閱它的集合的更改處理程序,並在集合中的事件少於2件時拋出異常。C#集合是否存在「Atomic Move」操作?

是這樣的(非常簡化,邊緣情況下不處理等)

public class ViewModel 
{ 
    private Model _model; 

    public ObservableCollection<Thing> Things { get; set; } 
    public Thing SelectedThing { get; set; } 

    public ViewModel(Model model) 
    { 
     _model = model; 

     Things = new ObservableCollection<Thing>(_model.Things); 
     // Some other code that ensures the model and viewmodel collections stay in sync 
     // ... 
    } 

    public void MoveUp() 
    { 
     var selected = SelectedThing; 

     int i = Things.IndexOf(selected); 
     Things.Remove(selected); // Throws exception 
     Things.Insert(i - 1, selected); 
    } 
} 

public class Model 
{ 
    public ObservableCollection<Thing> Things { get; set; } 

    public Model() 
    { 
     Things = new ObservableCollection 
     { 
      new Thing(), 
      new Thing() 
     }; 

     Things.CollectionChanged += CollectionChangedHandler; 
    } 

    private void CollectionChangedHandler(object sender, CollectionChangedEventArgs e) 
    { 
     if(e.Action == CollectionChangedAction.Remove) 
     { 
      if(Things.Count < 2) 
      { 
       throw new YouCantDoThatException(); 
      } 
     } 
    } 
} 

基本上,當用戶點擊「上移」,所選擇的項目被暫時從集合中刪除與上述這是其中插入之前。儘管這對於模型來說是一個無效的狀態,但我無法改變模型,因爲它是一個用於很多其他事情的API。有沒有辦法在C#做一個「原子移動」操作,這將允許我移動該項目而不先刪除它?

回答

3

我看到兩個選項:

  1. 使用由的ObservableCollection提供的 「移動」 功能。缺點是你的代碼處於只有一個項目的狀態(儘管時間很短),但是你的異常不會拋出,因爲CollectionChanged在移動完成之前不會被引發。

  2. 顛倒你的邏輯,並在刪除之前執行插入操作。您可以使用InsertItem(index,item)函數和RemoveAt(index)命令執行此操作。

通常,由於「交換」操作的工作原理,不存在「原子」移動的情況。您需要將「第一個」值分配給臨時值,將第二個值分配給第一個值,然後將溫度值分配給第二個值。某些彙編操作可以使這個「Atomic」在最純粹的意義上,但這對NotifyCollectionChanged沒有幫助。另外,您可以從ObservableCollection派生並實現您自己的移動算法,除非需要移動才能具有其他功能,否則不應執行此操作。 (MSDN)。

+0

我試圖避免從observablecollection派生,但它可能是我唯一的選擇。我會檢查移動方法,我不知道我是如何錯過的。 – ConditionRacer

+0

移動實際上做我需要做的事情。謝謝! – ConditionRacer

+0

剛剛運行檢查時,我附加了一個監聽器,它告訴我變更時的集合狀態。當我移動一個項目時,我收到的集合作爲事件源顯示新項目集合的新版本。 – Chris

相關問題