目录
此案例应用WPF+MVVM+Prism7.1。源码
-
应用场景
使用Prism7开发WPF程序,编码采用MVVM形式。当程序启动时,首先进入一个登陆界面,进行登陆认证,认证成功后转入程序布局主窗口。
-
设计思路
WPF程序框架搭建后,程序中存一个Shell.xaml,相当于表演者的唯一舞台。登陆窗体(以下简称 LoginView)和程序布局主窗体(以下简称 MainView),分别利用IRegionManager进行管理,根据需要在不同时机相继出场表演。所有操作均由各自ViewModel(简称VM)代码完成。
1.当程序启动后,Shell通过VM,使用RegionManager的Add方法激活LoginView。登陆操作后,发送消息loginState消息。该消息的发送是通过一个自定义的消息发送和订阅类来完成的(程序中将定义为:LoginSentEvent)。
2.Shell通过VM接受LoginSentEven传递的loginState来接收登陆成功与否的消息,如果登陆成功,则使用RegionManager的Deactivate方法使LoginView处于非激活隐藏。利用 Add方法使MainView视图激活。如果不成功呢,当然不改变视图了,继续登陆操作。
-
主要编码实现
建立Prism程序过程再此不再描述。这不是本文讨论重点:
1.App.xaml 的交互逻辑
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<Shell>();
}
}
这里主要实现Shell,也就是搭舞台。
2.Shell.xaml视图
<Window x:Class="rzSoft.Views.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:rzSoft.Views"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="Shell" Height="450" Width="800">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadDataCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<ContentControl prism:RegionManager.RegionName="MainRegion"/>
</Grid>
</Window>
Shell.xaml中通过引用System.Windows.Interactivity,使用EventTrigger绑定LoadDataCommand方法,使其在VM中实现View Loaded时进行相应的操作。
3.ShellViewModel
class ShellViewModel : BindableBase
{
IEventAggregator ea;
IContainerExtension _container;
IRegionManager _regionManager;
IRegion _region;
Login loginView;
MainWindow mainView;
private string _title = "Prism Unity Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public DelegateCommand LoadDataCommand { get; private set; }
//构造函数
public ShellViewModel(IContainerExtension Container, IRegionManager regionManager, IEventAggregator eventAggregator)
{
#region 接受登陆消息
ea = eventAggregator;
ea.GetEvent<LoginSentEvent>().Subscribe(MessageReceived);
#endregion
_regionManager = regionManager;
_container = Container;
LoadDataCommand = new DelegateCommand(loadData);
}
private void MessageReceived(bool loginState)
{
if (loginState)
{
_region.Deactivate(loginView);
mainView = _container.Resolve<MainWindow>();
_region.Add(mainView);
Title = "现在是程序主窗体";
//do other ...
}
}
private void loadData()
{
_region = _regionManager.Regions["MainRegion"];
loginView = _container.Resolve<Login>();
Title = "用户登陆";
_region.Add(loginView);
}
}
loaddata()方法在视图加载后运行,主要做了几项工作:
1.MainRegion被注册
2.Login和MainWindow被实例化,
3.loginView被加入激活。
4.其它:利用事件聚集器用于接受登陆消息,实现消息处理方法。
4.管理登陆事件的发布和订阅的类
public class LoginSentEvent : Prism.Events.PubSubEvent<bool> { }
5.Login /LoginViewModel
<UserControl x:Class="rzSoft.Views.Login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:local="clr-namespace:rzSoft.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel>
<TextBlock FontSize="50" HorizontalAlignment="Center"> 登陆窗体</TextBlock>
<Button Command="{Binding LoginCmd}" Margin="5" Padding="3" >登陆</Button>
</StackPanel>
</UserControl>
public class LoginViewModel : BindableBase
{
IEventAggregator ea;
public LoginViewModel(IEventAggregator aggregator)
{
LoginCmd = new DelegateCommand(LoginMethod);
ea = aggregator;
}
public DelegateCommand LoginCmd { get; private set; }
private void LoginMethod()
{
//登陆操作
bool loginState = true;
//登陆操作成功后,发送消息
ea.GetEvent<LoginSentEvent>().Publish(loginState);
}
}
点登陆按钮后,通过GetEvent发送一个登陆消息
shellViewModel接受消息后,有一个MessageReceived方法,负责隐藏登陆视图,激活主视图。
private void MessageReceived(bool loginState)
{
if (loginState)
{
_region.Deactivate(loginView);
_region.Add(mainView);
Title = "现在是程序主窗体";
//do other ...
}
}
MainWindow没什么内容,就是一个UserControl窗口控件
<UserControl x:Class="rzSoft.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:rzSoft.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d" Height="450" Width="800">
<Grid>
<TextBlock FontSize="50" VerticalAlignment="Center" HorizontalAlignment="Center"> 这是主窗体</TextBlock>
</Grid>
</UserControl>
以上内容,仅个人工作记录,不当指处,请斧正!