WPF MVVM - 如何将服务注入 ViewModel

WPF MVVM - how to inject a service into the ViewModel

我是 WPF 和 MVVM 的新手,我需要创建一个简单的对话框功能,允许我在屏幕上弹出一条确认消息,例如 "Confirm delete?" 和 y/n 按钮。我为此创建了一个对话服务(本质上是 System.Windows.MessageBox 的简单包装器),我想在我的整个应用程序中使用它。据我了解,我应该通过我所有 ViewModel 的构造函数注入此服务,如下所示:

public MainWindowViewModel(IDialogService injectedDialogService) // Dialog service dependency injection
{
    dialogService = injectedDialogService;
    ...
    ...
}

我在相应的 ViewModel 中声明 dialogService 为:

 private IDialogService dialogService;

然后我希望像这样在整个 ViewModel 中使用它:

dialogService.ShowDialog("Some message...");

或者,像这样:

if (dialogService.ShowDialog("Confirm delete?", "Confirmation",  DialogButtons.YesNo) == DialogResult.Yes)
{
    // Delete it...
}

但是,我从各自的视图中收到以下投诉:

The type "MainWindowViewModel" does not include any accessible constructors.

当我编译解决方案时,视图中出现以下错误消息:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

这就是我将视图与 ViewModel 相关联的方式:

<Window.Resources>
        <vm:MainWindowViewModel x:Key="MainWindowViewModel"/>
        ...
        ...
        ...
</Window.Resources>

和数据上下文:

<Window.DataContext>
        <vm:MainWindowViewModel/>
</Window.DataContext>

如果这有帮助,这是我的对话服务:

namespace FIM.Framework.Services
{
    public enum DialogButtons
    {
        OK = 0,
        OKCancel = 1,
        YesNoCancel = 3,
        YesNo = 4,
    }

    public enum DialogResult
    {
        None = 0,
        OK = 1,
        Cancel = 2,
        Yes = 6,
        No = 7,
    }

    public enum DialogImage
    {
        None = 0,
        Error = 16,
        Hand = 16,
        Stop = 16,
        Question = 32,
        Exclamation = 48,
        Warning = 48,
        Information = 64,
        Asterisk = 64,
    }

    public interface IDialogService
    {
        DialogResult ShowDialog(string messageBoxText, 
                                        string caption = null,
                                        DialogButtons buttons = DialogButtons.OK,
                                        DialogImage icon = DialogImage.None,
                                        DialogResult defaultResult = DialogResult.None);
    }

    public class DialogService : IDialogService
    {
        public DialogResult ShowDialog(string messageBoxText, 
                                       string caption = null, 
                                       DialogButtons buttons = DialogButtons.OK, 
                                       DialogImage image = DialogImage.None, 
                                       DialogResult defaultResult = DialogResult.None)
        {
            return (DialogResult)System.Windows.MessageBox.Show(messageBoxText, 
                                                                caption,
                                                                (System.Windows.MessageBoxButton)buttons,
                                                                (System.Windows.MessageBoxImage)image,
                                                                (System.Windows.MessageBoxResult)defaultResult);
        }
     }
}

你能帮我解决这个问题吗?如果我的方法是错误的,或者不是最好的,有人可以建议一个更好的对话服务实现吗? 非常感谢。

由于您的 MainWindowViewModel 需要一个参数,您不能在 xaml 中实例化它。您需要覆盖 App.xaml 文件的代码隐藏中的 OnStartup()


  1. 在 App.xaml 中删除 StartupUri="MainWindow.xaml"
  2. 在 App.xaml 的代码隐藏中,覆盖 OnStartup(StartupEventArgs e):

protected override void OnStartup(StartupEventArgs e)
{
     base.OnStartup(e);

     var viewmodel = new MainWindowViewModel(new DialogService());
     var window = new MainWindow { DataContext = viewmodel };
     window.Show();
 }