2022学习WPF初识MVVM框架prism完成菜单切换
- 首先新建一个wpf项目,选择最新的.net5.然后在包管理器里面安装 Prism.DryIoc包。就包含了Prism框架和容器。
- 我们在主窗体mainview里面新建两行,一行放按钮,一行放内容,显示动态切换的内容,内容呢来自于2个不同的用户控件 ,然后我们在内容里面设置prism的区域,并指定名称,代码如下
<Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal"> <Button Margin="5" Content="打开模块BtnA" Command="{Binding OpenCommand}" CommandParameter="WindowA"></Button> <Button Margin="5" Content="打开模块BtnB" Command="{Binding OpenCommand}" CommandParameter="WindowB"></Button> </StackPanel> <ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" ></ContentControl>
同时在窗体声明的xml文档里面加上 xmlns:prism="http://prismlibrary.com/" ,对Prism的引用,我们对每个按钮设置了command命令,并指定了参数。这里很关键。
- 我们在app.xaml.cs里面让我们的app这个类继承PrismApplication,这样我们就是我们就可以重载他里面的两个函数,一个是注册Navigation,这里我们注册windowA和windowB。另外一个是CreateShell。完整代码如下
public partial class App : PrismApplication { protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<WindowA>(); containerRegistry.RegisterForNavigation<WindowB>(); } protected override Window CreateShell() { return Container.Resolve<MainView>(); } }
最后我们定义一个类MainVieModel来承载窗体的数据。这个类需要继承BindableBase。然后定义一个 IRegionManager,通过构造函数注入进来,我们定义一个命令的属性,名称OpenCommad,类型是DelegateCommand,这是一个委托,可以定义是一个输入string类型的输入参数DelegateCommand<string>,然后在构造函数里面我们进行实例化,传入一个方法,方法的定义里面,可以根据 IRegionManger的找到所有的区域,然后根据区域名称找到我们页面上定义的区域,通过RequestNavgate方法,传入名称。就是方法的参数。代码如下
public class MainViewModel:BindableBase { private readonly IRegionManager _regionManager; public DelegateCommand<string> OpenCommand { get; private set; } public MainViewModel(IRegionManager regionManager) { _regionManager = regionManager; OpenCommand = new DelegateCommand<string>(Open); } private void Open(string obj) { //根据名字找到区域 _regionManager.Regions["ContentRegion"].RequestNavigate(obj); } }
最后我们需要指定窗体的data。 this.DataContext = new MainViewModel(_regionManager); 当然这里,也需要构造函数注入的形式,注入IRegionManger。
好了,我通过点击不同button,可以显示不同窗体下的内容,我们是通过名称参数传递的,最终效果如下,