MVVM 设计模式中的确认窗口

Rah*_*hod 3 c# wpf mvvm

嗨,我想在单击按钮时显示确认窗口。我正在尝试使用 MVVM 设计模式进行开发,我已经实现了,但我不认为在 viewModel 中调用视图
是正确的方法。我已经附上了代码,请检查它是否正确

<Window x:Class="MessegeBox_Demo_2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button Content="Ckick ME" HorizontalAlignment="Left" 
                    Command="{Binding GetMessegeboxCommand}"
                    Margin="200,131,0,0" VerticalAlignment="Top" Width="75"/>

        </Grid>
    </Window>

public class MainWindowViewModel : ViewModelBaseClass
{
   private ICommand _getMessegeboxCommand;
   public ICommand GetMessegeboxCommand
   {
      get
      {
          return _getMessegeboxCommand ?? (_getMessegeboxCommand = new MessegeBox_Demo_2.Command.realyCommand(() => ShowUsercontrol(), true));
      }
   }
   private void ShowUsercontrol()
   {
      MessegeBox_Demo_2.View.Window1 mbox = new View.Window1();
      mbox.ShowDialog();
   }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*yck 8

最简单的方法是实现一个 dialogservice 并使用依赖注入将服务注入到视图模型中。可以依赖于接口,但不能依赖于具体实现。
以下是我使用的界面:

namespace DialogServiceInterfaceLibrary
{
    public enum MessageBoxButton  
    {
    // Summary:
    //     The message box displays an OK button.
    OK = 0,
    //
    // Summary:
    //     The message box displays OK and Cancel buttons.
    OKCancel = 1,
    //
    // Summary:
    //     The message box displays Yes, No, and Cancel buttons.
    YesNoCancel = 3,
    //
    // Summary:
    //     The message box displays Yes and No buttons.
    YesNo = 4,
    }

    public enum MessageBoxResult
    {
    // Summary:
    //     The message box returns no result.
    None = 0,
    //
    // Summary:
    //     The result value of the message box is OK.
    OK = 1,
    //
    // Summary:
    //     The result value of the message box is Cancel.
    Cancel = 2,
    //
    // Summary:
    //     The result value of the message box is Yes.
    Yes = 6,
    //
    // Summary:
    //     The result value of the message box is No.
    No = 7,
    }

    // Summary:
    //     Specifies the icon that is displayed by a message box.
    public enum MessageBoxIcon
    {
    // Summary:
    //     No icon is displayed.
    None = 0,
    //
    // Summary:
    //     The message box contains a symbol consisting of white X in a circle with
    //     a red background.
    Error = 16,
    //
    // Summary:
    //     The message box contains a symbol consisting of a white X in a circle with
    //     a red background.
    Hand = 16,
    //
    // Summary:
    //     The message box contains a symbol consisting of white X in a circle with
    //     a red background.
    Stop = 16,
    //
    // Summary:
    //     The message box contains a symbol consisting of a question mark in a circle.
    Question = 32,
    //
    // Summary:
    //     The message box contains a symbol consisting of an exclamation point in a
    //     triangle with a yellow background.
    Exclamation = 48,
    //
    // Summary:
    //     The message box contains a symbol consisting of an exclamation point in a
    //     triangle with a yellow background.
    Warning = 48,
    //
    // Summary:
    //     The message box contains a symbol consisting of a lowercase letter i in a
    //     circle.
    Information = 64,
    //
    // Summary:
    //     The message box contains a symbol consisting of a lowercase letter i in a
    //     circle.
    Asterisk = 64,
    }

    public interface IDialogService
    {
        bool OpenFileDialog(bool checkFileExists,string Filter, out string FileName);
        void OpenGenericDialog(object Context,IRegionManager RegionManager);
    MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon);
    }
Run Code Online (Sandbox Code Playgroud)

和实施:

public class DialogService : IDialogService
{
    public bool OpenFileDialog(bool checkFileExists, string Filter, out string FileName) 
    {
        FileName = ""; 
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Multiselect = false;
        //openFileDialog.Filter = "All Image Files | *.jpg;*.png | All files | *.*";
        openFileDialog.Filter = Filter;
        openFileDialog.CheckFileExists = checkFileExists;
        bool result = ((bool)openFileDialog.ShowDialog());
        if (result)
        {
            FileName = openFileDialog.FileName;
        }
        return result;
    }


    public void OpenGenericDialog(object Context,IRegionManager RegionManager)
    {
        GenericDialogWindow dlg = new GenericDialogWindow(Context,RegionManager);
        dlg.Owner = System.Windows.Application.Current.MainWindow;
        dlg.Show();
    }

    public MessageBoxResult ShowMessageBox(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon)
    {
        return (DialogServiceInterfaceLibrary.MessageBoxResult)System.Windows.MessageBox.Show(message, caption, 
            (System.Windows.MessageBoxButton)buttons,
            (System.Windows.MessageBoxImage)icon);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将 IDialogservice 注入到视图模型中。接口和具体实现通常在不同的程序集中

MainWindowViewModel(IDialogService dialogservice){
    _dialogservice = dialogservice;
}

private void ShowUsercontrol()
{
   _dialogservice.ShowMessageBox(... //you get what i mean ;-)
}
Run Code Online (Sandbox Code Playgroud)

dialogservice 能够像打开文件对话框一样打开标准的 Windows 对话框。也可以使用通用版本,但是您需要了解稍微复杂一点的棱镜。Prism 还允许使用交互请求从视图模型到视图进行通信。我更喜欢在 Prism 中的这种工作方式,但如果您不了解 Prism,请忘记那句话。对于一个简单的确认窗口来说,它可能太复杂了。像这样的简单对话服务非常适合简单的确认窗口。

通过视图模型的构造函数注入您的依赖项,使您已经朝着使用控制反转容器的正确方向前进。并允许更轻松的单元测试,因为您可以模拟注入的接口以检查它们是否被正确调用等等。