MVVM在分离项目时显示来自VM的新窗口



我的问题涉及到一千零一个主题,如果我忽略了问题的答案,我很抱歉,但就我所见,没有人能真正回答我的问题。例如:在MVVM WPF 中打开新窗口

如果你只使用一个WPF项目(包括模型、vm和视图),答案是可以的,但由于我正在学习如何以正确的方式实现MVVM(我已经读过多次,最佳实践是为模型创建单独的类库(dll),viewmodel和一个单独的gui项目),这在我看来似乎不起作用,因为如果我想创建一个像IWindowService这样的接口(在以前的url和这里都有描述,它不可能访问Window或Control类,因为那样我就应该有一个gui项目的引用,而模式的整个目标就被破坏了。

因此,我的问题是如何从MainViewModel中显示一个新窗口(带有新的视图模型),同时尊重松散耦合的MVVM原则和独立的项目。

我正在努力实现的更深入的例子:

我有以下结构:

模型(dll项目)
 nbsp nbsp 配置文件

VIEWMODEL(dll项目)
nbsp nbsp nbsp;MainViewModel
 nbsp nbsp AddProfileViewModel

VIEW(WPF)(exe项目)
nbsp nbsp nbsp;主窗口
 nbsp nbsp AddProfileWindow

我打开MainWindow,想按下AddProfile按钮,然后AddProfileWindow需要显示并附带AddProfileViewModel。

  • 在模型项目中定义IWindowService接口
  • 从视图模型项目中引用模型项目
  • 在WPF应用程序(视图)项目中实现IWindowService

然后,该按钮应绑定到使用IWindowService打开窗口的ICommand。类似这样的东西:

public class MainWindowViewModel
{
private readonly IWindowService _windowService;
public MainWindowViewModel(IWindowService windowService)
{
_windowService = windowService;
AddProfile = new DelegateCommand(() =>
{
_windowService.OpenProfileWindow(new AddProfileViewModel());
});
}
public ICommand AddProfile { get; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel(new WindowService());
}
}
public class WindowService : IWindowService
{
public void OpenProfileWindow(AddProfileViewModel vm)
{
AddProfileWindow win = new AddProfileWindow();
win.DataContext = vm;
win.Show();
}
}

我一直在努力解决这个问题,发现@mm8发布的答案和其他一些帖子都很有帮助。我并不热衷于为每个视图创建一个类(或类中的方法)的想法,所以我创建了自己的变体。这是我在尝试使用MVVM时使用WPF的第一个项目之一,所以我会分享这一点,以防有帮助,并从更有经验的人那里获得反馈。

public class WindowDialogService : IWindowDialogService
{
private static readonly Dictionary<Type, Type> viewModelPairs =
new Dictionary<Type, Type>
{
[typeof(DetailsViewModel)] = typeof(DetailsView)
};
public void ShowWindowDialog(IViewModelBase viewModel)
{
if (!viewModelPairs.TryGetValue(viewModel.GetType(), out Type viewType))
{
throw new ArgumentException("View Model not mapped", nameof(viewModel));
}
if (viewType.GetConstructor(Type.EmptyTypes).Invoke(new object[] { }) is Window view)
{
view.DataContext = viewModel;
view.Owner = Application.Current.MainWindow;
view.ShowDialog();
}
}
}

相关内容

最新更新