silverlight开发实例(Prism+MVVM+RIA)(二)--创建shell及用户登录

在上篇基本说清了本项目的基本框架,下面开始说下项目的加载和shell。开始之前在建立EF时出现了一个问题,我在数据库中建立了视图,而在EF导入视图时出现因无法匹配主键导致无法导入视图的问题,检查发现是由于视图中sql语句中用了Union,先见Union语句取消再建立EF。

1、首先是建立项目启动的入口程序Bootstrapper,这个类由MefBootstrapper 继承,前面的Blog中已经说明。

2、关于用户登录界面的建立。有2种方式,一种是先建立登录界面,在登录成功后进入Shell。另一种是先建立Shell,然后在Shell启动后加载登录窗口。本例采用的是后者。现在的问题是由于采用MEF+MVVM方式,如何在Shell启动时加载登录窗口,同时在确认登录后进入Shell主窗口。本人采用的是通过在shell初始化时获取登录窗口然后加载,如下:

[html] view plaincopy
 
  1. protected override void InitializeShell()  
  2.         {  
  3.             base.InitializeShell();  
  4.             App.Current.RootVisual = (UIElement)this.Shell;  
  5.             ChildWindow view = ServiceLocator.Current.GetInstance(typeof(LoginForm)) as ChildWindow;  
  6.             view.Show();  
  7.         }  

这样就能够在Shell启动的时候加载登录窗口,见图:

3、登录窗口加载完成,新的问题是如何在Childwindow确认密码或密码错误时,触发窗口关闭或重新输入密码,本例根据网上查到的资料采用的是在Childwindow中添加附加属性的方式,利用附加属性绑定到ViewModel中的一个Bool属性,由此属性的变更引发窗口关闭,另外由于如果密码输入错误需要重新输入而不是关闭窗口,为了简化,在Childwindow中的Closing事件中加入的CodeBehind代码判断是否关闭窗口,不知谁还有好的办法可以交流下。

Childwindow附加属性类:

[csharp] view plaincopy
 
  1. public static class ChildwindowDialogResult  
  2.    {  
  3.        public static readonly DependencyProperty DialogResultProperty =  
  4.            DependencyProperty.RegisterAttached("DialogResult", typeof(Boolean?), typeof(ChildwindowDialogResult),  
  5.                                                new PropertyMetadata(OnSetDialogResultCallback));  
  6.        public static void SetDialogResult(ChildWindow childWindow, Boolean? dialogResult)  
  7.        {  
  8.            childWindow.SetValue(DialogResultProperty, dialogResult);  
  9.        }  
  10.        public static Boolean? GetDialogResult(ChildWindow childWindow)  
  11.        {  
  12.            return childWindow.GetValue(DialogResultProperty) as Boolean?;  
  13.        }  
  14.        private static void OnSetDialogResultCallback(DependencyObject dependencyObject,  
  15.                                                      DependencyPropertyChangedEventArgs e)  
  16.        {  
  17.            var childWindow = dependencyObject as ChildWindow;  
  18.            if (childWindow != null) childWindow.DialogResult = e.NewValue as bool?;  
  19.        }  
  20.    }  


ChildWindow的Xaml文件

[html] view plaincopy
 
  1. <controls:ChildWindow x:Class="SLFrameWork.View.LoginForm"  
  2.            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  3.            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
  4.            xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"  
  5.            xmlns:AttachPropertyInMVVM="clr-namespace:SLFrameWork.Web.Proxy.Common;assembly=SLFrameWork.Web.Proxy"  
  6.   
  7.            Width="400" Height="300"  
  8.            AttachPropertyInMVVM:ChildwindowDialogResult.DialogResult="{Binding DialogResult,Mode=TwoWay}"  
  9.            Title="用户登录" Closing="ChildWindow_Closing" Style="{StaticResource ChildWindowStyle1}">  
  10.       
  11.       
  12.     <Grid x:Name="LayoutRoot" Margin="2" >  
  13.         <Grid.RowDefinitions>  
  14.             <RowDefinition />  
  15.             <RowDefinition Height="Auto" />  
  16.         </Grid.RowDefinitions>  
  17.   
  18.         <Button x:Name="CancelButton" Content="取消" Command="{Binding Cancle}" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />  
  19.         <Button x:Name="OKButton" Content="确定" Command="{Binding Confirm}" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />  
  20.     </Grid>  
  21. </controls:ChildWindow>  


ChildWindow的后置代码

[csharp] view plaincopy
 
  1. [Export]  
  2.    public partial class LoginForm : ChildWindow  
  3.    {  
  4.        [ImportingConstructor]  
  5.        public LoginForm(LoginViewModel vm)  
  6.        {  
  7.            InitializeComponent();  
  8.            this.DataContext = vm;  
  9.        }  
  10.   
  11.         
  12.   
  13.        private void ChildWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)  
  14.        {  
  15.            if (this.DialogResult == false)  
  16.            {  
  17.                e.Cancel = true;  
  18.            }  
  19.        }  
  20.    }  


登录窗口的ViewModel

[csharp] view plaincopy
 
  1. using System;  
  2. using System.Net;  
  3. using System.Windows;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Documents;  
  6. using System.Windows.Ink;  
  7. using System.Windows.Input;  
  8. using System.Windows.Media;  
  9. using System.Windows.Media.Animation;  
  10. using System.Windows.Shapes;  
  11. using SLFrameWork.Web.Proxy.Common;  
  12. using System.ComponentModel.Composition;  
  13. using Microsoft.Practices.Prism.Commands;  
  14. using SLFrameWork.Web.Proxy.Common.Events;  
  15.   
  16. namespace SLFrameWork.ViewModel  
  17. {  
  18.     [Export]  
  19.     public class LoginViewModel:MyViewModelBase  
  20.     {  
  21.         public LoginViewModel()  
  22.         {   
  23.         }  
  24.         private bool? _dialogResult;  
  25.         public bool? DialogResult  
  26.         {  
  27.             get { return _dialogResult; }  
  28.             set  
  29.             {  
  30.                 _dialogResult = value;  
  31.                 RaisePropertyChanged("DialogResult");  
  32.             }  
  33.         }  
  34.   
  35.         ICommand _confirm;  
  36.         public ICommand Confirm  
  37.         {  
  38.             get  
  39.             {  
  40.                 if (_confirm == null)  
  41.                 {  
  42.                     _confirm = new DelegateCommand(OnConfirm);  
  43.                 }  
  44.                 return _confirm;  
  45.             }  
  46.         }  
  47.   
  48.         void OnConfirm()  
  49.         {  
  50.             MessageBox.Show("登录成功!");  
  51.             this.DialogResult = true;  
  52.         }  
  53.   
  54.         ICommand _cancle;  
  55.         public ICommand Cancle  
  56.         {  
  57.             get  
  58.             {  
  59.                 if (_cancle == null)  
  60.                 {  
  61.                     _cancle = new DelegateCommand(OnCancle);  
  62.                 }  
  63.                 return _cancle;  
  64.             }  
  65.         }  
  66.   
  67.         void OnCancle()  
  68.         {  
  69.             MessageBox.Show("重新登录!");  
  70.             this.DialogResult = false;  
  71.         }  
  72.     }  
  73. }  


本实例尚未加任何逻辑,不过过程基本描述清楚,下面只需要在ViewModel中加入自己的业务逻辑即可实现用户登录了!

原文地址:https://www.cnblogs.com/tianciliangen/p/4961346.html