WPF MVVM - как внедрить сервис в ViewModel - PullRequest
0 голосов
/ 23 января 2020

Я довольно новичок в WPF и MVVM, и мне нужно создать простую диалоговую функцию, которая позволяет мне выводить на экран сообщение с подтверждением, такое как «Подтвердить удаление?» с кнопками y / n. Я создал для этого диалоговую службу (которая по сути является простой оболочкой вокруг System. Windows .MessageBox), и я хотел бы использовать ее во всем приложении. Как я понимаю, я должен внедрить этот сервис через конструктор всех моих моделей представления следующим образом:

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

Я объявил dialogService в соответствующей модели представления как:

 private IDialogService dialogService;

И затем Я надеялся использовать его во всей ViewModel следующим образом:

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

Или вот так:

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

Однако я получаю следующую жалобу из соответствующего View:

Тип "MainWindowViewModel" не включает никаких доступных конструкторов.

И следующее сообщение об ошибке из представления при компиляции решения:

System.NullReferenceException: 'Ссылка на объект не установлена ​​для экземпляра объекта.'

Вот как я соотносю View с 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);
        }
     }
}

Можете ли вы помочь мне с этой проблемой? Если мой подход неправильный или не самый лучший, может кто-нибудь предложить лучшую реализацию для службы диалога? Большое спасибо.

1 Ответ

2 голосов
/ 23 января 2020

Поскольку ваш MainWindowViewModel ожидает параметр, вы не можете создать его экземпляр в xaml. Вам необходимо переопределить OnStartup() в коде вашего файла App.xaml.


  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();
 }
...