我们在桌面WPF世界中。让我们想象下面的场景(〜用户故事)。
窗口A 是一个对话框窗口,用于在数据库中添加或编辑实体A.其中一个字段是对其他实体的引用。为方便用户,添加实体B"添加实体B"按钮。
当用户按下此按钮时,正在显示 Window B ,其功能类似 - 添加或编辑实体B.当用户按下OK时,实体将被添加到数据库并返回,这样它可以被 Window A 用于在某个字段中自动设置。
现在让我们讨论技术问题。 WindowA
支持WindowAViewModel
。按下按钮会调用WindowAViewModel.CreateBEntity
方法。什么呢?
WindowAViewModel
到WindowB
的依赖关系以及我不想要的东西要做。WindowAViewModel
可以通过界面拨打WindowA
,说IWindowAAccess
要求新的EntityB
。然后WindowA
可以实例化WindowB
,然后接收新创建的实体并将其传递回WindowAViewModel
。这会在WindowA
和EntityB
之间产生依赖关系,但我想这是可以接受的。或者不是?WindowAViewModel
可能会要求某些IDialogService
执行整个操作。然后实现DialogService
将创建WindowB
并执行整个操作,返回EntityB
。但是,从服务到特定视图创建依赖关系是否可以接受?解决这个问题的正确方法是什么?
编辑: Another question讨论了类似的问题。但是,我有一些可能的解决方案,可能有效也可能无效,我想知道它们是否可以使用(因为在讨论的问题中提出的解决方案对我来说有点过分)
答案 0 :(得分:0)
在caliburn.micro世界中,您可以使用IWindowManager.ShowDialog(ModelView)
。
使用IoC,将WindowManager
注入IWindowManager
Bootstrapper
,然后将IWindowManager
添加到ViewModel
构造函数中。掌握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);
}
}
答案 1 :(得分: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);