C# 对话窗口MVVM方式
我们在桌面WPF世界。让我们设想以下场景(~用户故事) 窗口A是用于在数据库中添加或编辑实体A的对话框窗口。其中一个字段是对其他实体的引用。为了方便用户,有“添加实体B”按钮 当用户按下此按钮时,窗口B将显示,其作用类似于添加或编辑实体B。当用户按下OK时,实体将被添加到数据库并返回,以便窗口A可以使用它在某些字段中自动设置 现在我们来讨论技术问题C# 对话窗口MVVM方式,c#,wpf,mvvm,C#,Wpf,Mvvm,我们在桌面WPF世界。让我们设想以下场景(~用户故事) 窗口A是用于在数据库中添加或编辑实体A的对话框窗口。其中一个字段是对其他实体的引用。为了方便用户,有“添加实体B”按钮 当用户按下此按钮时,窗口B将显示,其作用类似于添加或编辑实体B。当用户按下OK时,实体将被添加到数据库并返回,以便窗口A可以使用它在某些字段中自动设置 现在我们来讨论技术问题WindowA由WindowAViewModel支持。按下按钮将调用WindowAViewModel.CreateBEntity方法。然后呢 我不能
WindowA
由WindowAViewModel
支持。按下按钮将调用WindowAViewModel.CreateBEntity
方法。然后呢
- 我不能简单地创建窗口B的实例,因为这将创建从
到WindowAViewModel
的依赖关系,而这是我不想做的事情WindowB
可以通过接口调用WindowAViewModel
,比如WindowA
请求新的IWindowAAccess
。然后EntityB
可以实例化WindowA
,然后接收新创建的实体并将其传递回WindowB
。这将在WindowAViewModel
和WindowA
之间创建依赖关系,但我想这是可以接受的。还是不EntityB
可能会要求一些WindowAViewModel
执行整个操作。然后实现,IDialogService
将创建DialogService
,并执行整个操作,返回WindowB
。但是,创建从服务到特定视图的依赖关系是否可以接受EntityB
编辑:讨论类似的问题。但是,我有一些可能的解决方案,可能有效,也可能无效,我想知道它们是否可以使用(因为在讨论的问题中提出的解决方案对我来说似乎有点过头了)。在世界上,您可以使用
IWindowManager.ShowDialog(ModelView)
使用IoC,将WindowManager
注入IWindowManager
中的Bootstrapper
,并将IWindowManager
添加到ViewModel
构造函数中。手头有iWindows Manager
,请拨打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);
}
}
公共类AppBootstrapper:BootstrapperBase
{
// ...
受保护的覆盖无效配置()
{
container.Singleton();
}
}
公共类调用视图模型
{
专用只读iWindows管理器windowManager;
公共调用视图模型(iWindows管理器windowManager)
{
this.windowManager=windowManager;
}
公共方法()
{
var called=newcalledviewmodel();
var result=windowManager.ShowDialog(调用);
//处理结果
}
}
名为dviewmodel的公共类:Screen
{
公共无效Ok()
{
TryClose(真);
}
公开作废取消()
{
TryClose(假);
}
}
最后一点你做得很好
如果您要求某些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);
我问了一个非常类似的问题,一个家伙给了我一个很好的使用命令的方法。然后你可以使用泛型和其他东西来让它更花哨。这就是我不相信服务是解决MVVM对话框问题的好方法的原因之一。事实上,仅使用视图模型就可以完成所有工作,行为调用对话框本身的创建。您可能想看看.MVVM对话框总是很有趣,您可能想看看这两个开源项目中的实现:注意,这与导航基本上是同一个问题,所以请接近您已经为导航设计的内容