2012-07-06 56 views
4

我是MVVM(和一些WPF)的新手,在過去的幾天裏我已經閱讀了許多代碼項目文章,博文和Stackoverflow問題。我有這樣的印象:數據綁定對從數據源(數據庫)加載數據後顯示數據非常好,並且保持模型與視圖同步,並更新視圖中模型數據的所有其他外觀。驗證和保存WPF MVVM中的數據如何正常工作?

但我仍然沒有真正知道如何節省,而驗證之前,應該工作的權利。我有一個強大的Windows窗體和ADO.NET背景。我非常熟悉編碼數據庫訪問層和視圖更新。那時候,您只有臨時的臨時數據,正在編輯,只有在視圖中,以及模型類和數據庫中最後保存的數據版本。模型類通常與數據庫同步。這是包含尚未保存的數據的觀點。

你也有一個保存按鈕,將來自控制讀取的所有數據,在代碼驗證它,要麼接受,並將其保存到模型和數據庫,或者不更新模型,並顯示一條錯誤消息。如果發生錯誤,用戶輸入仍留在用戶界面中供用戶修改。但是沒有其他應用程序可以看到它。而且你有一個取消按鈕,它只會丟棄包含編輯控件的視圖的那一部分 - 該模型仍然有效並保持不變。

使用數據綁定和的ViewModels剛剛從模型類,什麼是在文本框中輸入暴露數據

現在立即進入模型,是它正確與否。 IDataErrorInfo只不過是 - 信息性的。您可以將其視爲或忽略它。唯一實施的嚴格驗證是類型轉換:永遠不能將非數字字符串更新爲數字模型字段。但就是這樣。我將通過讓ViewModel執行所有驗證並從屬性設置器中拋出對無效數據的異常來解決這個問題。這是實現已知行爲的唯一方法。

但哪裏保存和數據的丟棄去?我什麼時候會將數據寫回數據庫? TextBox的每個離開都會導致數據庫寫入,因此我不再需要顯式的Save命令(並且只能通過撤消來恢復)?我何時會驗證整個數據記錄?我將如何處理模型和數據庫不同步,無效輸入立即傳播整個應用程序和所有視圖感謝數據綁定?何時以及如何使用「取消」按鈕放棄任何用戶輸入,保持模型不變 - 或者在編輯器對話框打開之前將其恢復到狀態?

我覺得MVVM不提供這些基本問題的解決方案。我只是想念他們還是他們真的不存在?如果MVVM不是這個的解決方案,那麼是什麼?或者MVVM最好不要用於WPF中的數據編輯應用程序?

+1

嘗試交叉張貼到http://programmers.stackexchange.com/您的問題(關於軟件開發概念性問題) – Surfbutler 2012-07-06 13:17:54

回答

4

MVVM不回答這些問題,你 - 你有靈活性,在任何你選擇的方式來解決數據庫寫(功率負擔?)。如果您需要在保存回數據庫之前收集所有數據,則可以這樣做 - 只需在ViewModel上添加一個綁定到SaveCommand的Save按鈕,該按鈕將執行您的數據訪問存儲過程/實體框架更新方法/無論如何。如果你想單獨記錄每一位數據,那麼你需要在其他地方調用數據訪問過程(可能是視圖模型上的屬性設置器?)

本質上,MVVM不是一個完整的端對端數據庫,終端軟件模式。它只查看用戶看到的內容(列表框,文本框和按鈕)與應用程序本身之間的通信。您的數據訪問代碼,序列化,存儲,持久性,無論您使用的是什麼,無論您使用的是什麼,都將在應用程序代碼(模型)中保留在應用程序的MVVM端。不管你喜歡,你都可以寫這個。

我正在寫一個應用程序,用戶填寫表單並點擊保存或取消。保存和取消都是綁定到ViewModel上的命令的按鈕。在ViewModel構造函數中,模型對象的屬性被複制到ViewModel的屬性中。在保存時,ViewModel的屬性被複制回模型的屬性,並啓動數據訪問代碼。在取消時,模型的屬性被複制到ViewModel的屬性上。

class MyViewModel 
{ 
    public MyViewModel(MyModel model) 
    { 
     this.Name = model.Name; 
     this.Colour = model.Colour; 
    } 

    public string Name {get;set;} 
    public string Colour {get;set;} 

    // commands here that connect to the following methods 

    public void Save() 
    { 
     model.Name = this.Name; 
     model.Colour = this.Colour; 
     model.SaveToDatabase(); 
    } 

    public void Cancel() 
    { 
     this.Name = model.Name; 
     this.Colour = model.Colour; 
    } 

} 

這是一個簡單的方法來做到這一點 - 當然,你需要在INotifyPropertyChanged引發和它的其餘部分,還有其他的選擇。但我覺得這種方法很容易理解正在發生的事情,並且有很好的基礎來添加其他任何可能需要查找的內容。

+0

謝謝皮特。所以你說(在這些情況下)ViewModel包含Model的數據的_copy_,並且不僅僅傳遞所有get和set請求到模型實例?因爲這是我在例子和教程中經常看到的,我認爲這將是最好的方式。也許我只是沒有對自己想要複製數據的模式做一點修改。 – ygoe 2012-07-06 14:01:27

+0

也許是因爲他們說驗證應該進入模型。並且爲了驗證在編輯過程中產生效果,數據需要直接導入到模型中...因此,以您的示例爲例,我認爲驗證將完全進入ViewModel,對吧? – ygoe 2012-07-06 14:07:17

+0

是的 - 你可以使用'DataAnnotations'屬性更快地進行驗證,或者進行自定義驗證。如果你也想在模型上使用驗證/而不是,你需要稍微修改這個東西 - 也許把VM屬性掛鉤到模型的一個單獨的,斷開的實例(使用'Clone()'或者其他方法? )並且用'Save()'同步這兩者。我仍然在玩弄自己並且探索自己的答案,但是我遠離框架來理解問題和不同的方式。玩得開心! – 2012-07-06 14:21:06

0

我認爲您將ViewModel與數據庫混淆,您的視圖綁定到ViewModel在離開TextBox時,TextBox中的任何內容都將被分配給ViewModel的對象,該對象仍在內存中。您將需要一個保存按鈕,MVVM僅僅是一個模式,用於分離傳統視圖和代碼,以便進行解耦和簡單的單元測試。保存按鈕被點擊後,您仍然需要執行數據驗證。爲了放棄用戶輸入並恢復到之前的狀態,您可以在編輯之前保存您的ViewModel數據,或者使用Entity Framework來跟蹤和管理數據更改。

1

使用MVVM,可以將視圖中的控件綁定到ViewModel中的屬性和命令。該模型代表您的數據庫。

驗證用戶輸入可以通過多種方式完成。你可以限制文本框只接受某些數據,你可以驗證屬性設置等數據等

我不是數據庫專家,但我會收集我的虛擬機中的信息,並添加一個保存按鈕的視圖中的某個地方驗證數據並將其寫入數據庫。取消按鈕可以用來自模型(數據庫)的(不變的)值覆蓋VM屬性。

(編輯:什麼皮特說:)