基于MVVM Light的MahApps DialogCoordinator正确MVVM实现问询
Hey there! Let's work through getting that IDialogCoordinator injected into your ViewModels in the MyProject.Core project without a hitch. Here's a step-by-step breakdown of the common solutions:
1. Direct Injection (Core depends on MahApps)
If you don't mind your Core project having a dependency on MahApps' dialog library, this is the quickest approach:
Step 1: Add MahApps Dialogs NuGet to Core
First, install the MahApps.Metro.Controls.Dialogs NuGet package in your MyProject.Core class library. This lets the Core project recognize the IDialogCoordinator interface.
Step 2: Register DialogCoordinator in Presentation
In your MyProject.Presentation WPF app (usually in App.xaml.cs or your ViewModelLocator), register the singleton instance of DialogCoordinator with MVVM Light's SimpleIoc:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // Register the DialogCoordinator singleton SimpleIoc.Default.Register<IDialogCoordinator>(() => DialogCoordinator.Instance); // Register your ViewModels here too SimpleIoc.Default.Register<MyViewModel>(); }
Step 3: Inject into ViewModel
Now you can inject IDialogCoordinator directly into your Core ViewModel's constructor:
using MahApps.Metro.Controls.Dialogs; using GalaSoft.MvvmLight; namespace MyProject.Core.ViewModels { public class MyViewModel : ViewModelBase { private readonly IDialogCoordinator _dialogCoordinator; // Constructor injection public MyViewModel(IDialogCoordinator dialogCoordinator) { _dialogCoordinator = dialogCoordinator; // Initialize commands or other logic here } // Example usage in a command private async void ShowDialog() { await _dialogCoordinator.ShowMessageAsync(this, "Success!", "Dialog injected correctly!"); } } }
2. Decoupled Approach (Core doesn't depend on MahApps)
If you want to keep your Core project clean of UI framework dependencies, use dependency inversion by creating your own abstraction:
Step 1: Define a Dialog Service Interface in Core
Create a simple interface in MyProject.Core that outlines the dialog functionality you need:
namespace MyProject.Core.Services { public interface IDialogService { Task ShowMessageAsync(string title, string message); // Add other dialog methods (confirm, input, etc.) as needed } }
Step 2: Implement the Service in Presentation
In MyProject.Presentation, create a concrete implementation that uses MahApps' DialogCoordinator:
using MahApps.Metro.Controls.Dialogs; using MyProject.Core.Services; namespace MyProject.Presentation.Services { public class MahAppsDialogService : IDialogService { private readonly IDialogCoordinator _dialogCoordinator; public MahAppsDialogService(IDialogCoordinator dialogCoordinator) { _dialogCoordinator = dialogCoordinator; } public async Task ShowMessageAsync(string title, string message) { // Use the injected DialogCoordinator to show the dialog await _dialogCoordinator.ShowMessageAsync(this, title, message); } } }
Step 3: Register Services with SimpleIoc
Back in your Presentation project's startup code, register both the IDialogCoordinator and your custom IDialogService:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); SimpleIoc.Default.Register<IDialogCoordinator>(() => DialogCoordinator.Instance); SimpleIoc.Default.Register<IDialogService, MahAppsDialogService>(); SimpleIoc.Default.Register<MyViewModel>(); }
Step 4: Inject Your Custom Service into ViewModel
Now your Core ViewModel only depends on your own IDialogService, no MahApps references needed:
using MyProject.Core.Services; using GalaSoft.MvvmLight; namespace MyProject.Core.ViewModels { public class MyViewModel : ViewModelBase { private readonly IDialogService _dialogService; public MyViewModel(IDialogService dialogService) { _dialogService = dialogService; } private async void ShowDialog() { await _dialogService.ShowMessageAsync("Success!", "Decoupled dialog service works!"); } } }
Common Troubleshooting Tips
- "IDialogCoordinator not found": Make sure you've installed the correct MahApps NuGet package in the project where you're referencing the interface.
- Dialogs don't show up: Ensure you're passing the ViewModel instance (
this) when calling dialog methods—MahApps uses this to find the associated window context. - ViewModel not resolving: Double-check that your ViewModels are registered in
SimpleIocand that theViewModelLocatoris correctly set up in your XAML.
内容的提问来源于stack exchange,提问作者chrizator

