2015-10-08 107 views
4

我們在桌面WPF世界。我們來想象下面的場景(〜用戶故事)。對話窗口MVVM方式

窗口A是用於在數據庫中添加或編輯實體A的對話框窗口。其中一個字段是對其他實體的引用。爲了方便用戶,有「添加實體B」按鈕。

當用戶按下該按鈕時,窗口正在顯示,其用於類似的作用 - 添加或編輯實體B.當用戶按下OK,實體正被添加到數據庫中並返回,使得它可以用於通過窗口A在某些領域自動設置它。

現在讓我們來討論技術問題。 WindowA支持WindowAViewModel。按下按鈕導致調用WindowAViewModel.CreateBEntity方法。然後什麼?

  • 我不能簡單地創建櫥窗內的情況下,因爲這將產生依賴從WindowAViewModelWindowB和這件事情我不想做的事。
  • WindowAViewModel可以通過接口呼叫WindowA,比如IWindowAAccess要求新的EntityB。然後WindowA可以實例化WindowB,然後接收新創建的實體並將其傳遞迴WindowAViewModel。這將創建WindowAEntityB之間的依賴關係,但我想這是可以接受的。或不?
  • WindowAViewModel可能會要求一些IDialogService執行整個操作。然後執行DialogService將創建WindowB並執行整個操作,返回EntityB。但是,從服務到特定視圖創建依賴關係還可以接受嗎?

解決此問題的正確方法是什麼?


編輯:Another question討論了類似的問題。然而,我有一些可能的解決方案,可能或不可能有效,我想知道它們是否可以使用(因爲在討論的問題中提出的解決方案似乎對我有點矯枉過正)。

+0

我問真的類似這樣的問題,一個人給我用命令的相當好辦法。然後你可以使用泛型和其他東西來使它更加花哨。請參閱http://stackoverflow.com/questions/32739791/showing-a-modal-dialog-and-getting-results –

+0

這是我不相信服務是解決MVVM對話框的好方法的原因之一問題。實際上可以單獨使用視圖模型來執行所有操作,而行爲調用創建對話框本身。你可能想看看[我在代碼項目網站上寫過的一篇長篇文章](http://www.codeproject.com/Articles/820324/Implementing-Dialog-Boxes-in-MVVM)。 –

+0

MVVM對話框總是很有趣,你可能想看看這兩個開源項目中的實現:https://github.com/ButchersBoy/MaterialDesignInXamlToolkit和https://github.com/MahApps/MahApps.Metro –

回答

0

caliburn.micro世界中,您可以使用IWindowManager.ShowDialog(ModelView)來做到這一點。

使用IOC,注入WindowManagerIWindowManagerBootstrapper,並添加IWindowManagerViewModel構造。手中有IWindowManager,請致電ShowDialog

代碼示例:

public class AppBootstrapper : BootstrapperBase 
{ 
    // ... 

    protected override void Configure() 
    { 
     container.Singleton<IWindowManager, WindowManager>(); 
    } 
} 

public class CallingViewModel 
{ 
    private readonly IWindowManager windowManager; 

    public CallingViewModel(IWindowManager windowManager) 
    { 
     this.windowManager = windowManager; 
    } 

    public Method() 
    { 
     var called = new CalledViewModel(); 
     var result = windowManager.ShowDialog(called); 

     // handle result 
    } 
} 

public class CalledViewModel : Screen 
{ 
    public void Ok() 
    { 
     TryClose(true); 
    } 

    public void Cancel() 
    { 
     TryClose(false); 
    } 
} 
0

你是在用最後一點好辦法。

如果您要求IDialogService創建WindowB,您不必將它與WindowB結合,因爲WindowB是一個參數。

public IDialogService { 
    public bool? ShowDialog(Type dialogType); //there is no dependency to concrete dialog. 
} 

dialogService.ShowDialog(typeof(WindowB)); 
//or 
dialogService.ShowDialog(typeof(WindowBViewModel)); 

如果你需要更多的信息傳遞給窗口中,你可以做以下之一:

var dialogViewModel = new WindowBViewModel(); 
dialogViewModel.Parameter = parameter; 
dialogService.ShowDialog(dialogViewModel); 

//or 
dialogService.ShowDialog(typeof(WindowBViewModel), parameter); 
+0

通知,這與導航基本上是一樣的問題,所以請保持接近你已經設計的導航 – Liero