好的取消 Dialog MVVM Pattern wpf.How can I do it

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4199162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:19:52  来源:igfitidea点击:

Ok cancel Dialog MVVM Pattern wpf.How can I do it

wpfmvvm

提问by user9969

I am working on a MVVM wpf application and I need to show various dialogs with ok cancel. I have seen few on the net but the look overcomplicated or may be its me struggling.

我正在开发一个 MVVM wpf 应用程序,我需要显示带有 ok 取消的各种对话框。我在网上看到的很少,但看起来过于复杂,或者可能是我在挣扎。

I Have noticed that many that use "IDialogService"

我注意到许多使用“IDialogService”

Can anybody point me to a link or has a snippet handy on how to implement a Dialog using a MVVM Pattern?

任何人都可以指向我的链接或有一个关于如何使用 MVVM 模式实现对话框的方便的片段吗?

thanks a lot

多谢

回答by ihatemash

here is a barebones dialog with OK and Cancel buttons. I have included the XAML, View, and ViewModel:

这是一个带有 OK 和 Cancel 按钮的准系统对话框。我已经包含了 XAML、View 和 ViewModel:

XAML:

XAML:

<Window
    x:Class="TestProject.Views.OKCancelDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    Title="Window Title"
    Height="300"
    Width="600"
    WindowStartupLocation="CenterOwner"
    WindowStyle="ToolWindow"
    ResizeMode="CanResize"
    UseLayoutRounding="True"
    TextOptions.TextFormattingMode="Display">

    <Grid>
        <Button
            Name="OKButton"
            Content="OK"
            Height="23"
            HorizontalAlignment="Right" 
            Margin="0,0,93,12"
            VerticalAlignment="Bottom" 
            Width="75" 
            Click="OKButton_Click"
            IsDefault="True"
            Command="{Binding OKButtonCommand}" />

        <Button
            Name="CancelButton"
            Content="Cancel" 
            Height="23" 
            HorizontalAlignment="Right" 
            Margin="0,0,12,12"
            VerticalAlignment="Bottom"
            Width="75" 
            IsCancel="True" />
    </Grid>
</Window>

Codebehind:

代码隐藏:

using System.Windows;
using TestProject.ViewModel;

namespace TestProject.Views
{
    public partial class OKCancelDialog : Window
    {
        private readonly OKCancelViewModel viewModel;

        //I use DI to inject the ViewModel into the View
        //This will allow you to use the view for different ViewModels if you need to.
        //Create an Interface for your ViewModel to implement to make ViewModel unit testing
        //easier. Testing frameworks such as rhino mock require Interfaces to test methods
        //in a class under test and it allows you to use an IoC Container to create the
        //ViewModel for you.                 
        public OpenReturnDialog(IOKCancelViewModel viewModel)
        {
            InitializeComponent();
            this.viewModel = viewModel; //Do this if you need access to the VM from inside your View. Or you could just use this.Datacontext to access the VM.
            this.DataContext = viewModel;
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }

    }
}

ViewModel

视图模型

using Microsoft.Practices.Composite.Presentation.Commands;


namespace TestProject.ViewModel
{
    public class OKCancelViewModel
    {
        public OKCancelViewModel()
        {
            OKButtonCommand = new DelegateCommand<object>(HandleOKButtonCommand, CanExecuteOKButtonCommand);
        }

        public DelegateCommand<object> OKButtonCommand { get; private set; }

        public void HandleOKButtonCommand(object obj)
        {
             //Here is where your code for OK button clicks go.

        }

        public bool CanExecuteOKButtonCommand(object obj)
        {
            //Put code to determine when the OK button will be enabled/disabled.
        } 

        //You may want to add a command for the Cancel button also if you have a need to 
        //enable/disable the cancel button
        //The command will look just like the OK button command above.
    }
}

Now, you will most likely want to have your ViewModel implement INotifyPropertyChanged in the event you have other controls in your UI that will bind to properties in the ViewModel.

现在,如果您的 UI 中有其他控件将绑定到 ViewModel 中的属性,您很可能希望让您的 ViewModel 实现 INotifyPropertyChanged。

Hope this helps...

希望这可以帮助...

回答by JP Richardson

I think everyone else that uses an IDialogService or actually creates their own dialogs is over engineering the problem. I really like the simplistic approach of using Funcs. Here is an example. First add this to your ViewModel:

我认为使用 IDialogService 或实际创建自己的对话框的每个人都过度设计了问题。我真的很喜欢使用 Funcs 的简单方法。这是一个例子。首先将其添加到您的 ViewModel:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    /** Other ViewModel Code *//

    public Func<string, string, bool> OkCancelDialog { get; set; }
}

Then when you instantiate your derived class of your ViewModel, you just attach the following code: (I typically do this in the startup like Program.cs)

然后,当您实例化 ViewModel 的派生类时,您只需附加以下代码:(我通常在启动时执行此操作,如 Program.cs)

var myVM = new SomeSuperViewModel();
myVM.OkCancelDialog = (msg, caption) => MessageBox.Show(msg, caption, MessageBoxButton.OkCancel) == MessageBoxResult.OK;

In your actual ViewModel code, all you have to do is call:

在您的实际 ViewModel 代码中,您所要做的就是调用:

if (OkCancelDialog("Some crazy message.", "Caption"))
    //do something if true
else
    //else do something if false

In your unit tests you can do this:

在您的单元测试中,您可以这样做:

var myVMToTest = new SomeSuperViewModel();
myVMToTest.OkCancelDialog = (msg, caption) => true; //could be false too if you need to test that functionality.

I prefer this approach, as it's simple and easy to test. What do other's think?

我更喜欢这种方法,因为它简单且易于测试。别人怎么看?

回答by jbe

You might have a look at the ViewModel(EmailClient) sample application of the WPF Application Framework (WAF). It shows how to write custom dialogs with MVVM and it shows how you can use the MessageBox without violating the MVVM pattern.

您可能会查看WPF 应用程序框架 (WAF)ViewModel(EmailClient) 示例应用程序。它展示了如何使用 MVVM 编写自定义对话框,并展示了如何在不违反 MVVM 模式的情况下使用 MessageBox。

回答by Peregrine

What's wrong with just calling System.Windows.MessageBox.Show() from the code of your ViewModel

仅从 ViewModel 的代码中调用 System.Windows.MessageBox.Show() 有什么问题

e.g.

例如

public bool GetConfirmation(string Message, string Caption)
{ return MessageBox.Show(Message, 
                         Caption, 
                         System.Windows.MessageBoxButton.OKCancel, 
                         System.Windows.MessageBoxImage.Question, 
                         System.Windows.MessageBoxResult.Cancel) == System.Windows.MessageBoxResult.OK; }