Prism MVVM应用 登陆后切换主窗体实现

目录

应用场景

设计思路

编码实现

       此案例应用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>

        以上内容,仅个人工作记录,不当指处,请斧正!

源码 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值