2012-07-09 49 views
2

我對WPF MVVM模型很新穎,請耐心等待。我正在嘗試編寫一個庫存管理系統。我有一個維護頁面,可以成功鏈接到我的視圖模型。不過,我想啓用一個可以從維護頁面觸發的搜索控件,以彈出一個網格,用戶可以在其中搜索一個項目,選擇它並返回到維護屏幕,其中所選項目是showm。WPF MVVM關於彈出搜索的建議

在MVVM中如何最好地實現這種類型的功能?維護屏幕上的搜索按鈕可以鏈接到搜索ICommand,但Viewmodel沒有關於UI的知識,因此它不知道顯示搜索控件的名稱或如何顯示它。我能想到的唯一想法就是在代碼背後編寫搜索按鈕事件,但不會破壞MVVM模式?

在此先感謝和道歉,如果這是一個愚蠢的問題。

+0

實際上是把一段代碼,在後面的代碼不會打破這種模式。 MVVM的關鍵點是可以單元測試視圖邏輯(viewmodel)而不存在veiw。 – ktutnik 2012-07-09 10:27:31

回答

1

這裏的主要問題是如何以MVVM友好的方式顯示搜索彈出窗口。我在我的github帳戶上有一個example專用於此目的的自定義控件(完整的源代碼可供下載)。

的控制可以被用於這樣的:

<c:ModalContentPresenter IsModal="{Binding DialogIsVisible}"> 

    <!-- This is the main content e.g. your maintenance screen --> 
    <TabControl Margin="5"> 
      <Button Margin="55" 
        Padding="10" 
        Command="{Binding ShowModalContentCommand}"> 
       This is the primary Content 
      </Button> 
     </TabItem> 
    </TabControl> 

    <c:ModalContentPresenter.ModalContent> 
     <!-- This is the modal content e.g. your search popup --> 
     <Button Margin="75" 
       Padding="50" 
       Command="{Binding HideModalContentCommand}"> 
      This is the modal content 
     </Button> 
    </c:ModalContentPresenter.ModalContent> 

</c:ModalContentPresenter> 

模態內容直接顯示在主內容(在你的情況下通過維持屏幕)和它的可見性被控制由IsModal屬性可以是結合到viewModel中的一個屬性。該屬性將通過搜索命令設置爲true,並且您的搜索網格將顯示在維護屏幕前面。

您的搜索屏幕「視圖」會有一個關閉按鈕,該按鈕綁定到另一個ICommand對象,該對象將該屬性設置爲false並隱藏彈出內容。

請注意,由於主要模式內容和模式內容都由相同的控件管理,因此它們共享相同的DataContext,在您的情況下,它們將是對viewModel的引用,因此不需要「傳遞」任何信息。

+0

謝謝Benjamin,我在我的庫存維護屏幕上成功實現了這一點。 – Oliver 2012-07-10 10:44:54

+0

優秀。我很高興別人能夠使用它。 – 2012-07-10 11:01:59

0

爲避免UI與視圖模型之間的直接耦合,我以前使用Mediator將新UI元素的創建轉發回UI類。然而,我從來沒有完全相信這種方法,所以有興趣看看有沒有人有更好的解決方案。

2

解決您的問題的一個好方法是使用User Interaction Patterns

就MVVM模式而言,視圖模型負責啓動與用戶的交互以及消費和處理任何響應,而視圖負責使用任何用戶體驗實際管理與用戶的交互是適當的。保持視圖模型中實現的表示邏輯與視圖實現的用戶體驗之間的關注點分離有助於提高可測試性和靈活性。

在MVVM模式中實現這些類型的用戶交互有兩種常見方法。一種方法是實現視圖模型可用於啓動與用戶交互的服務,從而保持其對視圖實現的獨立性。另一種方法是使用視圖模型引發的事件來表達與用戶交互的意圖,以及視圖中與這些事件相關的組件,並管理交互的視覺方面。

這是用於執行DialogServices等的MVVM模式,因此它也將符合您的要求。

+0

對於友好的交互鏈接+1 :) – MBen 2012-07-09 11:13:45

0

如果你的意思是寫Dialog時彈出對話框,那麼我會使用一個對話服務,如this之一。

在維護視圖模型opencommand:

var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);//in your case the viewmodel for your search 

//check the result and just take the SelectedItem from your dialogwindowVM 
if(result) 
    this._selected = dialogwindowVM.MySelectedItem;