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()
。
- 在 App.xaml 中删除
StartupUri="MainWindow.xaml"
。
- 在 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();
}
我是 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()
。
- 在 App.xaml 中删除
StartupUri="MainWindow.xaml"
。 - 在 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();
}