首先申明,本人是初学者,自己刚开始接触prism框架的时候,一点头绪没有,某站上的网课讲的都差不错,反正我自己也不太能听懂,只能跟着老师敲。后来我感觉其实你把老师讲的那几个知识点的代码分开来写稍微自己归纳一下就会清晰明了一些,本文纯属自己的学习笔记,用自己的大白话讲了一下自己的理解,如有错误欢迎指出。
紧接上文,分享一下我对区域管理的认识。
理解:
比如你的浏览器 上面是导航下面是页面 你点击导航里面的一些页面导航不会变 但是下面的部分就会变成对应的页面 这就是两个不同的区域,这样既不用新增一个窗口来显示这个页面 而且又方便好用。
实现:
前端:
创建一个Prism模板项目,在你的视图文件夹中创建三个用户控件(后面再说是干啥的),然后随便在三个用户控件中写点东西,可以区分就行,看看我的(B和C一样):
然后我们在主页面随便(真的很随意)放几个按钮,就相当于浏览器的导航栏:
这个时候注意,如果你是用prism模板项目生成的该项目,你的视图中会有这段代码
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />
这句话就是说 在我的Grid控件的第2行是一个区域,区域的名字叫做"ContentRegion "这个名字可以自己定义。也就是说,我的主页面的视图下面那一块空白区域是一个叫做ContentRegion的区域。接下来我们需要来控制这个区域,让他展示我们想要的页面(也就是我们定义的ABC三个用户控件)
后端:
一、申明一个IRegionManager接口类型的私有字段
private readonly IRegionManager _regionManager;
这里为什么要这么写,我其实也不太知道,我自己的理解是,后面可以直接用_regionManager这个字段来管理区域,很方便。(写多了就知道了)
二、将区域管理服务的实例regionManager 注入到构造函数中,并且接收
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
}
这里也有点不太好理解,但是我看人家都是这么写的,先写着吧,多写两次就知道了,我自己的理解就是,告诉编译器我要用区域管理这个服务了,然后我要用我先前定义的那个字段去管理。
三、绑定命令
现在,你已经告诉你的程序,你要使用区域管理了,你的程序也准备好了,但是你需要一个动作去让他开始管理,这就用到了上一篇文章写到的命令绑定,可以自己去看看。于是我们就有了接下来的操作,还记不记得我前面的主页面的视图,里面的三个按钮都绑定了OpenWindowCmm命令,并且分别传了三个参数:
<Button Command="{Binding OpenWindowCmm}" CommandParameter="AWindow" Content="A窗口" Height="30" Margin="5"/>
<Button Command="{Binding OpenWindowCmm}" CommandParameter="BWindow" Content="B窗口" Height="30" Margin="5"/>
<Button Command="{Binding OpenWindowCmm}" CommandParameter="CWindow" Content="C窗口" Height="30" Margin="5"/>
四、方法的实现
在你点击按钮之后,程序会跳到后端的OpenWindowCmm命令所指定的OpenCommand()方法中,并且带着你的参数。(这里的参数不是必须要和你的用户控件的名称一样,这里为了简洁)
OpenWindowCmm = new DelegateCommand<string>(OpenCommand);
private void OpenCommand(string obj)
{
//_regionManager.Regions["ContentRegion"].RequestNavigate(obj);
_regionManager.RequestNavigate("ContentRegion", obj); //该方法相当于用url或者视图名称进行导航
//_regionManager.Regions["ContentRegion"].RemoveAll();
//_regionManager.RegisterViewWithRegion("ContentRegion", obj);//RegisterViewWithRegion 该方法会缓存第一次使用的用户控件页面 若要使用就必须每一次都清除一下
}
看到没 ,这里就用了_regionManager,这个字段直接来管理你的那一块区域。这里有三种方法来,就拿一种来举例。RequestNavigate这个方法可以接受两个参数(实际不止,这里暂时用两个就够了)第一个是你要管理的区域的名字(就是我们主页面下面那一片空白区域的名字),第二个参数就是你要显示在其区域上的用户控件的名字,这里需要和你用户控件的名字一样。你传入的名字如果不一样,就需要进行别的操作后再传入RequestNavigate方法,这个不细说,可以自己去玩玩。
五、注册用户控件
我们来到App.xaml.cs中,将区域管理服务注入到我们的项目中,并且注册一下我们开始创建的三个用户控件,这样程序就可以根据我们的参数名找到对应的用户控件了,代码是这样的:
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<AWindow>();
containerRegistry.RegisterForNavigation<BWindow>();
containerRegistry.RegisterForNavigation<CWindow>();
}
IContainerRegistry containerRegistry:注入区域管理服务并创建containerRegistry实例
用containerRegistry实例注册三个用户控件。(人家都这么写)
到这里我们就完成了
效果:
就放两个了。
总结:
一、申明一个字段,用于管理区域
二、将区域管理服务的实例regionManager 注入到构造函数
三、在对应的命令方法中实现
完整代码:
前端:(主页面 用户控件很简单略过)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding OpenWindowCmm}" CommandParameter="AWindow" Content="A窗口" Height="30" Margin="5"/>
<Button Command="{Binding OpenWindowCmm}" CommandParameter="BWindow" Content="B窗口" Height="30" Margin="5"/>
<Button Command="{Binding OpenWindowCmm}" CommandParameter="CWindow" Content="C窗口" Height="30" Margin="5"/>
</StackPanel>
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />
</Grid>
后端:
MainWindowViewModel:
public class MainWindowViewModel : BindableBase
{
private readonly IRegionManager _regionManager;//申明一个IRegionManager接口类型的私有字段
public DelegateCommand<string> OpenWindowCmm { get; set; }
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
OpenWindowCmm = new DelegateCommand<string>(OpenCommand);
}
private void OpenCommand(string obj)
{
//_regionManager.Regions["ContentRegion"].RequestNavigate(obj);
_regionManager.RequestNavigate("ContentRegion", obj); //该方法相当于用url或者视图名称进行导航
//_regionManager.Regions["ContentRegion"].RemoveAll();
//_regionManager.RegisterViewWithRegion("ContentRegion", obj);//RegisterViewWithRegion 该方法会缓存第一次使用的用户控件页面 若要使用就必须每一次都清除一下
}
}
App.xaml
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<AWindow>();
containerRegistry.RegisterForNavigation<BWindow>();
containerRegistry.RegisterForNavigation<CWindow>();
}
}