Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对话窗口MVVM方式_C#_Wpf_Mvvm - Fatal编程技术网

C# 对话窗口MVVM方式

C# 对话窗口MVVM方式,c#,wpf,mvvm,C#,Wpf,Mvvm,我们在桌面WPF世界。让我们设想以下场景(~用户故事) 窗口A是用于在数据库中添加或编辑实体A的对话框窗口。其中一个字段是对其他实体的引用。为了方便用户,有“添加实体B”按钮 当用户按下此按钮时,窗口B将显示,其作用类似于添加或编辑实体B。当用户按下OK时,实体将被添加到数据库并返回,以便窗口A可以使用它在某些字段中自动设置 现在我们来讨论技术问题WindowA由WindowAViewModel支持。按下按钮将调用WindowAViewModel.CreateBEntity方法。然后呢 我不能

我们在桌面WPF世界。让我们设想以下场景(~用户故事)

窗口A是用于在数据库中添加或编辑实体A的对话框窗口。其中一个字段是对其他实体的引用。为了方便用户,有“添加实体B”按钮

当用户按下此按钮时,窗口B将显示,其作用类似于添加或编辑实体B。当用户按下OK时,实体将被添加到数据库并返回,以便窗口A可以使用它在某些字段中自动设置

现在我们来讨论技术问题
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对话框总是很有趣,您可能想看看这两个开源项目中的实现:注意,这与导航基本上是同一个问题,所以请接近您已经为导航设计的内容