2009-10-21 44 views
2

我有一個ViewModel封裝了一些選項對話框中正在編輯的屬性。我實際上無法將它們保存到設置中,直到它們碰到Ok按鈕,這會最終在此特定ViewModel上調用Commit。編寫一個可維護的提交方法

在我的ViewModel一個單一的屬性看起來是這樣的:

public bool SomeProperty 
{ 
    get 
    { 
     return m_SomeProperty; 
    } 
    set 
    { 
     if (m_SomeProperty != value) 
     { 
      m_SomeProperty = value; 
      NotifyPropertyChanged("SomeProperty"); 
     } 
    } 
} 
private bool m_SomeProperty = Properties.Settings.Default.SomeProperty; 

所以正常的執行情況提交將做到這一點:

public void Commit() 
{ 
    Properties.Settings.Default.SomeProperty = m_SomeProperty; 
    // Add other properties here... 
} 

這是沒有那麼糟糕,但原因我不喜歡這樣,如果你添加一個新的屬性,你必須在兩個地方添加代碼。我儘可能避免這種情況。

起初我以爲我可以聲明一個名爲OnCommit的私人事件,並讓Commit方法引發該事件,併爲每個屬性添加事件的事件處理函數的代碼,並寫入設置,但我不知道如何做到這一點,而無需在構造函數中添加事件處理程序,這無助於這種情況。

任何想法?有沒有人有一個優雅的方式來做我想做的事情?

編輯:感謝sixlettervariables的答案。我採納了這個想法,並將其納入SoapBox Core並公開了結果。看看選項對話框,看看它是如何工作的。

回答

4

也許保留要執行的Action的列表?

private List<Action> commitActions = new List<Action>(); 

public bool SomeProperty 
{ 
    get 
    { 
     return m_SomeProperty; 
    } 
    set 
    { 
     if (m_SomeProperty != value) 
     { 
      m_SomeProperty = value; 
      lock (commitActions) 
      { 
       commitActions.Add(
        () => Properties.Settings.Default.SomeProperty = value); 
      } 
      NotifyPropertyChanged("SomeProperty"); 
     } 
    } 
} 

然後通過行動更新Commit代碼迴路。

public void Commit() 
{ 
    List<Action> commits; 
    lock (commitActions) 
    { 
     commits = new List<Action>(commitActions); 
     commitActions.Clear(); 
    } 

    foreach (var commit in commits) 
    { 
     commit(); 
    } 
} 
+0

+1這聽起來像是對我最好的方式。 – 2009-10-21 14:31:44

+0

這是一個非常酷的想法。我意識到我也需要它來進行取消操作(將它們重置爲保存的值)。一個問題,但如果我只從GUI訪問這個,我需要鎖嗎? – 2009-10-21 14:33:33

+0

如果你真的只有一個線程訪問'commitActions',那麼你不需要鎖。鎖只是一個建議,如果代碼更多地涉及。此外,你可以考慮創建你自己的撤銷/重做類,其中包含一個「撤銷和重做」操作。 – user7116 2009-10-21 14:37:29

0

你可以使用反射來確定你的類有哪些屬性並遍歷它們?

+0

不確定。也許如果與某種lambda函數配對... – 2009-10-21 14:20:46