使用 MVVM LIGHT (WPF) 在用户控件中导航
本文关键字:用户 控件 导航 MVVM LIGHT WPF 使用 | 更新日期: 2023-09-27 18:33:18
首先,我为我的英语不好而道歉,这不是我的第一语言。
我是 MVVM 的新手,所以我的问题可能是一个非常新手的问题;)
我在使用 WPF 和 MVVM LIGHT 在 C# 应用程序中切换视图时遇到了一些问题。我已经读了很多文章,但我仍然无法弄清楚如何以干净的方式做到这一点。
所以我的问题来了:在 MainWindows 中包含的用户控件之间实现导航的最佳方法是什么,假设:
- 我为每个用户控件提供了一个视图模型,对于主窗口有一个视图模型。
- 用于在用户控件之间切换的按钮包含在用户控件本身中
- 我有一个视图模型定位器
- 我有时需要销毁/重新创建用户控件的视图模型
- 我想尊重 MVVM 模式。
- 我想保持简单
由于没有人回答我的问题,这就是我最终所做的。这可能不是最好的方法,但至少效果很好。我希望它能帮助一些像我这样正在努力学习这种模式的新手:
将 CurrentViewModel 对象放入 MainViewModel:
public class MainViewModel : ViewModelBase,IMainViewModel
{
/* Other piece of code */
private ViewModelBase _currentViewModel;
public ViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
_currentViewModel = value;
RaisePropertyChanged(() => CurrentViewModel);
}
}
}
显然,将其绑定到主视图(仅相关代码(:
<UserControl Content="{Binding Path=CurrentViewModel}"/>
将 DataTemplate 放在 App.xaml 中:
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
<DataTemplate DataType="{x:Type localViewModel:HomeViewModel }">
<localView:AccueilView/>
</DataTemplate>
<DataTemplate DataType="{x:Type localViewModel:ErrorViewModel }">
<localView:ErrorView/>
</DataTemplate>
</ResourceDictionary>
</Application.Resources>
在视图模型定位器中使用简单 IOC 注册视图模型:
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IHomeViewModel, DesignHomeViewModel>();
}
else
{
SimpleIoc.Default.Register<IHomeViewModel, HomeViewModel>();
}
将视图模型定位器中所有视图模型的获取器设置为静态(示例只有一个(
public static IHomeViewModel Home
{
get{return ServiceLocator.Current.GetInstance<IHomeViewModel>();}
}
由于它是静态的,您可以从 MainViewModel 访问所需的视图模型:
public class MainViewModel : ViewModelBase,IMainViewModel
{
public ViewModelBase HomeVM
{
get
{
return (ViewModelBase)ViewModelLocator.Home;
}
}
}
提供注销视图模型并重新创建它的功能:
public static void CleanUpHome()
{
SimpleIoc.Default.Unregister<HomeViewModel>();
SimpleIoc.Default.Register<IHomeViewModel, HomeViewModel>();
}
"子"视图模型通过消息与 MainViewModel 通信:
public class ErrorViewModel : ViewModelBase, IErrorViewModel
{
/*Other piece of code */
public void HomeReturn()
{
var msg = new ChangeView(ChangeView.EnumView.Home);
Messenger.Default.Send<ChangeView>(msg);
ViewModelLocator.CleanUpErrors();
}
}
MainViewModel 注册到消息并对其进行处理:
public class MainViewModel : ViewModelBase,IMainViewModel
{
public MainViewModel()
{
Messenger.Default.Register<ChangeView>(this, (action) => ReceiveMessage(action));
CurrentViewModel = HomeVM;
}
private void ReceiveMessage(ChangeView viewName)
{
switch (viewName.switchView)
{
case ChangeView.EnumView.Home:
CurrentViewModel = HomeVM;
break;
case ChangeView.EnumView.Error:
CurrentViewModel = ErrorVM;
break;
}
Messenger.Default.Unregister<ChangeView>(this, (action) => ReceiveMessage(action));
}
就这样。