2011-07-30 55 views
3

在我的Silverlight應用程序,用戶可以創建一個表單的多個模板。根據所選模板的不同,表單會按特定順序顯示一組視圖。此外,如果模板上有一些視圖是「必需的」。客戶希望這些視圖以彈出窗體的形式顯示,因此用戶首先關注那些「必需」視圖,然後再轉到窗體上的其他視圖。MVVM模式的模板形式

現在,我認爲我打破MVVM模式這一要求。這裏的原因... 1視圖模型可以用來讀取數據庫模板,搶的意見(使用MEF),但將它們添加到形式,它需要知道佈局網格的名稱,並添加視圖作爲一個孩子到那個網格。這就像告訴ViewModel關於違反MVVM設計模式的UI元素一樣。

  1. 對於必須顯示在彈出的「需要」的觀點,視圖模型將需要創建一個ChildWindow例如,添加「要求」意見,然後顯示Childwindow。還處理關閉/關閉事件。

我確定我的方法存在缺陷,但無法找到將UI邏輯與業務邏輯完全分開的方法。有人可以提供更好的方法。

謝謝。 一個

回答

0

下面是我想到的解決方案。

1.用帶有ViewModel關聯的視圖名稱的元標記裝飾ViewModels。

  1. 創建一個名爲ViewViewModel新的類,它擁有兩個屬性

    • 視圖名稱
    • 視圖模型實例。
  2. 在Form ViewModel上,它負責將所有視圖聚合在一起,並根據情況調出一個子窗口。添加三個屬性

    • 列表FormViews
    • 列表ChildWindowViews。
    • 行動ShowChildWindow

的FormView控件模型將需要實例化的ViewModels,從它的MEF元標記每個視圖模型收集視圖名稱和移植FormView和ChildWindowView性能。一旦Form ViewModel完成處理請求並且兩個屬性已經被填充,如果ChildWindow不爲空,它將使用true參數觸發ShowWindow委託。

  1. 窗體視圖會做以下

    • 佈局根將綁定到FormView控件屬性的StackPanel。將會有一個IValueConverter處理FormViews List中的每個條目。對於每個ViewName,它查找並創建視圖的實例。將DataContext設置爲ViewModel。

    • 當ShowChildWindow動作被引發時,在FormView中會有最小的代碼隱藏,它會創建並顯示綁定到ChildWindowViews屬性的ChildWindow。 ChildWindow屬性使用相同的IValueCOnverter創建所請求視圖的實例。

你覺得如何?請留言

enter code here 
3

恕我直言:這又是另一種情況只需添加控制器MVVM會解決所有問題乾淨利落。我們稱之爲MVCVM(恥辱,並不等同於有效的羅馬數字):)

,我們成功地使用最近所有項目的模式是註冊控制器,模塊,並在啓動時初始化它們。該控制器是很輕/苗條和需要的唯一的事情流連應用監聽,或發送郵件的生活。在他們的初始化方法中,他們然後註冊他們需要擁有的任何東西(視圖和視圖模型等)。這種輕量級的純邏輯內存模式也適用於更薄的應用程序(例如更適合WP7)。

正如你所發現的那樣,使用虛擬機的問題在於你最終遇到了需要了解視圖(這是他們不應該知道的一件事)的情況。

我們遵循的基本規則是:

  • 控制器使基於事件
  • 控制器獲取數據,並將其放置在適當的視圖模型屬性
  • 控制器設置視圖模型攔截事件的ICommand的性質決定
  • 控制器使意見出現(如果其他地方沒有暗示)
  • 視圖模型是「啞巴」。綁定和沒有別的
  • 意見保持數據知道他們顯示的數據有一定的形狀,但不知道它從何而來

最後兩點是你永遠不應該打破那些或分離關注走出了窗口。

到目前爲止,您需要虛擬機直接訪問數據庫(錯誤),虛擬機獲取視圖(很糟糕),並要求虛擬機彈出另一個窗口(非常糟糕)。

給它一些想法。您可能會到(重新)將控制器引入您的MVVM應用程序。如果你想要更多的信息,只需要問。

+0

Hello Hitech Magic。感謝您的詳細建議。鑑於這種情況,您能否提供一個小而簡單的例子來說明控制器如何在這種情況下提供幫助。我真的不想佔用你很多時間。一個簡單的例子可以幫助我找到正確的方向。謝謝A – user559788

+0

@ user559788:以上是一組通用規則(如MVVM)。爲了生成特定的實現示例,我需要更多關於您正在嘗試解決的問題的詳細信息。如果你想通過我的網站發送代碼,我們可以發回一些合適的東西,或者你可以在你的問題中發表更多的細節。歡呼 –

+0

Thx提供幫助HiTech。讓我整理一份乾淨的樣本,並在一兩天內發給你。 – user559788

0

在我們的項目中,我們一直關注事件訂閱機制,當UI需要完成特定的事情時,需要在視圖和視圖模型之間進行通信。解決問題的一種方法是在視圖模型上用視圖列表作爲事件參數發佈事件。或者可能有一個維護此列表的屬性,在視圖模型上設置,並在更新屬性時觸發事件。在視圖中,您可以訂閱該事件並將控件添加到佈局根目錄。這是可測試的解決方案,並不會在視圖模型中放入任何特定的視圖。

如果你有使用MVVM框架的自由,那麼你可以嘗試像PRISM或MVVMLight。 Prism提供事件協議器,而MVVMLight提供的Messenger類可以分離視圖和視圖模型以及不同視圖模型之間的通信。

+0

嗨Nilesh,我使用Prism和MVVM,但不是MVVmLight。我也使用棱鏡提供的事件發佈框架。我實際上是在要顯示錶單時發佈事件。該事件具有要顯示的視圖列表。我的「表單」視圖(而不是視圖模型)監聽事件,然後開始將請求的視圖放在一起,然後將它們添加到其佈局根。我試圖擺脫這種邏輯,因爲它迫使我在表單視圖中添加一些代碼隱藏。你有沒有解決方案,這個邏輯可以以某種方式移到視圖模型。 – user559788

+0

在後面的代碼中查看特定的邏輯並不壞。您可以通過MVVM Light Laurent Bungion的創建者觀看MVVM Deep Dive演示文稿,他在這裏提出了一些隱藏的代碼並不差。如果您使用MVVM,我認爲很多人認爲在代碼背後存在代碼是一種犯罪。 –

+0

這絕對不是。你應該試圖通過抽象邏輯來查看模型,儘可能地實現可測試性。如果存在需要使用代碼的情況,則可以使用它。視圖模型被綁定到視圖,因此後面的代碼意識到視圖模型的存在。我們不應該做的是讓視圖模型意識到視圖。只要我認爲在我看來分離的關注在使用代碼背後沒有問題。 –