使用 Prism 和 UWP 进行对话的正确方法
Proper way to do dialogs using Prism and UWP
我不确定我是否以正确的方式思考这个问题。我有一个对象列表,我希望用户能够编辑和查看指定对象的属性。我最初的想法很好,我会弹出一个带有文本框的对话框,让用户编辑他们想要的内容,直到他们按下“确定”或“取消”。
我在使用 UWP,并使用 Prism 满足我所有的 MVVM 需求。我花了一段时间,但我了解创建视图及其关联的视图模型、命令等。到目前为止,我认为我在保持视图逻辑和业务逻辑分离方面做得很好。
我搜索过,但没有找到如何以遵循 MVVM 原则的方式显示对话框。似乎最常出现的两件事是使用交互请求(在 UWP 上使用 Prism 似乎不存在),以及创建自定义内容对话框并通过在父视图的关联方法中调用 ShowAsync 来显示它ViewModel(这似乎与 MVVM 原则背道而驰)。
那么,我该如何显示一个使用 XAML 定义并具有关联的 ViewModel(最好是因为它与我所熟悉的相似)的对话框,或者我可以通过其他方式来解决这个问题有问题吗?
使用 MVVM 打开对话框的正确位置是在 ViewModel 中。
通常我会在你的场景中做这样的事情:
创建用于显示对话框的界面:
public interface IWindowService
{
void OpenViewModelInWindow(ViewModelBase vm, string title, bool resizeable = true);
void CloseViewModelInWindow(ViewModelBase vm);
}
在UI层实现这个接口:
public class WindowService : IWindowService
{
private List<Window> _windows = new List<Window>();
public void OpenViewModelInWindow(ViewModelBase vm, string title, bool resizeable = true)
{
var window = new Window
{
Title = title,
Content = vm,
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
ShowInTaskbar = false,
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = resizeable ? ResizeMode.CanResize : ResizeMode.NoResize
};
_windows.Add(window);
window.ShowDialog();
}
public void CloseViewModelInWindow(ViewModelBase vm)
{
_windows.Single(w => w.Content == vm).Close();
}
}
在您的 App.xaml 中,您需要定义 DataTemplates,以便在您设置 window 的内容 属性 时,在 window 中创建相应的视图。
<DataTemplate DataType="{x:Type viewModel:AViewModel}">
<views:AUserControl />
</DataTemplate>
然后你可以从ViewModel中使用IWindowService,你应该通过构造函数注入来注入它。
这样您就不会直接从 ViewModel 引用特定于框架的 类。 ViewModel 仅具有对 IWindowService 的引用。当您想要为视图模型编写单元测试时,这也有好处。您可以模拟此服务,以便在单元测试 运行 时它不应该打开对话框。
我不确定我是否以正确的方式思考这个问题。我有一个对象列表,我希望用户能够编辑和查看指定对象的属性。我最初的想法很好,我会弹出一个带有文本框的对话框,让用户编辑他们想要的内容,直到他们按下“确定”或“取消”。
我在使用 UWP,并使用 Prism 满足我所有的 MVVM 需求。我花了一段时间,但我了解创建视图及其关联的视图模型、命令等。到目前为止,我认为我在保持视图逻辑和业务逻辑分离方面做得很好。
我搜索过,但没有找到如何以遵循 MVVM 原则的方式显示对话框。似乎最常出现的两件事是使用交互请求(在 UWP 上使用 Prism 似乎不存在),以及创建自定义内容对话框并通过在父视图的关联方法中调用 ShowAsync 来显示它ViewModel(这似乎与 MVVM 原则背道而驰)。
那么,我该如何显示一个使用 XAML 定义并具有关联的 ViewModel(最好是因为它与我所熟悉的相似)的对话框,或者我可以通过其他方式来解决这个问题有问题吗?
使用 MVVM 打开对话框的正确位置是在 ViewModel 中。
通常我会在你的场景中做这样的事情:
创建用于显示对话框的界面:
public interface IWindowService
{
void OpenViewModelInWindow(ViewModelBase vm, string title, bool resizeable = true);
void CloseViewModelInWindow(ViewModelBase vm);
}
在UI层实现这个接口:
public class WindowService : IWindowService
{
private List<Window> _windows = new List<Window>();
public void OpenViewModelInWindow(ViewModelBase vm, string title, bool resizeable = true)
{
var window = new Window
{
Title = title,
Content = vm,
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
ShowInTaskbar = false,
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = resizeable ? ResizeMode.CanResize : ResizeMode.NoResize
};
_windows.Add(window);
window.ShowDialog();
}
public void CloseViewModelInWindow(ViewModelBase vm)
{
_windows.Single(w => w.Content == vm).Close();
}
}
在您的 App.xaml 中,您需要定义 DataTemplates,以便在您设置 window 的内容 属性 时,在 window 中创建相应的视图。
<DataTemplate DataType="{x:Type viewModel:AViewModel}">
<views:AUserControl />
</DataTemplate>
然后你可以从ViewModel中使用IWindowService,你应该通过构造函数注入来注入它。
这样您就不会直接从 ViewModel 引用特定于框架的 类。 ViewModel 仅具有对 IWindowService 的引用。当您想要为视图模型编写单元测试时,这也有好处。您可以模拟此服务,以便在单元测试 运行 时它不应该打开对话框。