从一个登录页面浅淡MVVM(一)

转自http://www.cnblogs.com/Sunpire/archive/2010/12/25/1916913.html

Silverlight 使用的是 MVVM 模式,可是有多少人在使用 MVVM ?我自己就没有。

在这里,我以一个登录页面为例子,和大家分享讨论一下 Silverlight 开发的一些点滴,

包括 Validation、MVVM 等。

 

不过要说明的是,我并没有学习过官方关于 MVVM 的文档,这个例子我是从实例中进行重构,

有所感受而写出来的,还是希望各位权威大侠进行指正,最好是有官方的文档,感激万分。

 

这个例子采用的是 Silverlight + WCF ,不是 Silverlight + WCF RIA Services,

如果您不熟悉 Silverlight + WCF ,请先学习这方面的内容。

 

这个例子分成三个阶段,分别是

一、MV模式(Model-View模式)

二、MVVM模式(Model-View-ViewModel模式)

三、MVVM模式,并使用Command

 

附:VS2010源代码下载 http://files.cnblogs.com/Sunpire/MVVMTutorial.zip

 

第一阶段:MV模式(Model-View模式)

其实,能使用MV模式,说明已经是入门了 Silverlight 了,有多少从ASP.NET、从Windows Form

转过来的朋友,不懂得 Binding、不懂得 Validation ,苦苦想要从 UI 中去访问数据,去校验数据。

 

这个例子的 WCF 端很简单,就是校验用户名、密码和验证码

 

WCF中的User类


namespace MVVMTutorial.Web.Models
{
[DataContract]
public class User
{
[DataMember]
public string UserName { get; set; }

[DataMember]
public string Password { get; set; }
}
}

复制代码

 

 很简单的按当前时间生成4位校验码,用户名为不区分大小的test、密码为小写的test时登录成功

LoginService.svc


namespace MVVMTutorial.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class LoginService
{
/// <summary>
/// 简单的记录校验码,为简单起见,认为校验码永久有效
/// </summary>
private static List<string> validationCodes = new List<string>();

/// <summary>
/// 生成简单的校验码
/// </summary>
/// <returns></returns>
[OperationContract]
public string GenerateValidationCode()
{
string ticks = DateTime.Now.Ticks.ToString();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = ticks.Length - 5; i >= ticks.Length - 8; i--)
{
sb.Append(ticks[i]);
}
if (!validationCodes.Contains(sb.ToString()))
{
validationCodes.Add(sb.ToString());
}
return sb.ToString();
}

/// <summary>
/// 简单登录判断
/// </summary>
/// <param name="usr"></param>
/// <param name="validationCode"></param>
/// <returns>1:用户名密码正确;0:用户名密码不正确;2:校验码无效</returns>
[OperationContract]
public short Login(Models.User usr , string validationCode)
{
if (!validationCodes.Contains(validationCode))
{
return 2;
}
if (usr != null && usr.UserName.ToLower() == "test" && usr.Password == "test")
{
return 1;
}
else
{
return 0;
}
}
}
}

复制代码

接下来就是 Silverlight 端,生成 LoginService.svc 的代理类

在代理 LoginProxy 的 Reference.cs 中,会生成 User 类的代码,

我会将其 Copy 出来,单独放在一个低层次的类库项目中,如上图的 Models 项目的 User.cs 文件,

为什么要这样做? 这是因为 Validation 的需要。

 

Validation 需要使用到 System.ComponentModel.DataAnnotations 中的各种 Attribute,

如 UserName 的写法是: 

User.cs 中的 UserName

 其中校验了 必填、长度为3-6字符、只能输入字母和数字 等,并且在前台UI的 Label 标签中显示为“用户名”等。

 PS:关于 Silverlight Validation,可以参考 jv9 的博客http://www.cnblogs.com/jv9/archive/2010/09/27/1836394.html

 

将 User 的 namespace 改为和 WCF 中的 User 的相同,生成 Models 项目,然后再更新 LoginProxy,

这样 Reference.cs 中不再含有对 User 的定义了。

 

Models 项目中存放的就是各种模型 Model,在实际项目中,绝对大数的 Model 来自于 WCF 中所使用到的

Entity,在这个例子中,还针对 校验码 增加了一个 ValidationModel ,用于表示校验码模型,这个模型只有

一种逻辑“校验码要和从WCF中取得的校验码相同”。 实际上,在WCF端并没有这个 Model,这里加上这个

Model,也是为了在 UI 应用 Binding 和 Validation。

 

接下来看 View 部分:

 

LoginPage.xaml

   

这里使用了 Binding 和 ValidationSummary,个人认为这是使用 Silverlight 入门的标志:)

下图是运时的效果

接下来是 LoginPage.cs 的全部代码,代码较多,这是因为没有使用 ViewModel 这一层嘛,哈哈。 

LoginPage.cs中的事件响应代码

使用了 User、ValidationModel 、LoginProxy.LoginServiceClient 三个实例,并且将前两者的实例作为

前台 UI 的 DataContext。

要指出的是在 btnLogin_Click() 有一段校验判断代码显得很臃肿,这是很无奈的,

Silverlight Validation机制是好,可是在UI的输入框不输入的情况下,点击[登录]按钮时,

this.validationSummary1是得不到任何校验的反馈的,this.validationSummary1.HasErrors == false,

此时只有手动的对各个控件的 Binding 进行验证,为此写了一个扩展方法:

ValidateSource()扩展方法

 

 

另外,在对 LoginProxy.LoginServiceClient 实例的使用上,每次WCF异步请求开始前都判断是否要初始化

WCF 代理,以防止页面在长时间搁置不动之后,WCF代理实例在达到超时时间后自动关闭,再次通过该实例

发送请求时便会出现 NOT FOUND 错误。

NeedInitializeClient

如果认为这是一个好习惯,可以将其写成扩展方法,如

NeedInitializeClient

 

下面是 WCF 异步请求完成的处理代码

InitializeClient()

简单起见都是使用MessageBox.Show()来处理异常或提示消息。

 

 

 

至此,这个例子的第一阶段完成了,这是一个完整的例子,

LogingPage.cs 中的代码也是相当清晰的了,

可是 LogingPage.cs 中必竟还是混杂了一些控制逻辑,这也导致了要进一步分离这些代码的需要,

这便是 ViewModel 层次。

 

二、MVVM模式(Model-View-ViewModel模式)

 

时间: 2012-04-10

从一个登录页面浅淡MVVM(一)的相关文章

从一个登录页面浅淡MVVM(三)

转自http://www.cnblogs.com/Sunpire/archive/2010/12/25/1916943.html 在 ViewModels 中增加一个 ViewModelCommand ,通过 Action<Object> 执行实际的方法.   ViewModelCommand.cs     PS:日前,在看有关 Object Value  的用法时,提到了 struct ,struct 是存储在 Heap 上,而引用类型是存储在 Stack 上的,在内存分配及垃圾回收等方面

从一个登录页面浅淡MVVM(二)

转自http://www.cnblogs.com/Sunpire/archive/2010/12/25/1916933.html 如上图,增加了一个 LoginViewModel.cs 文件,放在 ViewModels 目录中,这个文件就是 LoginPage 的 ViewModel . 一个 UI 对应一个 ViewModel ,这就是 MVVM 的要求,在 ASP.NET MVC 2 中,便是类似这样的. 下面是这个 ViewModel 的部分代码:  LoginViewModel.cs的字

wpf-WPF MVVM 如何做一个登录页面

问题描述 WPF MVVM 如何做一个登录页面 初学者想做一个登录页面,只是输入账号,在数据库里判断用户是否存在就行,用MVVM写就行,急用 解决方案 http://jingyan.baidu.com/article/d45ad1489336ca69552b803f.htmlhttp://www.silverlightchina.net/html/study/WPF/2013/0216/21847.html

java-在Android中写一个浏览器,加载一个登录页面如何获取用户名和密码框

问题描述 在Android中写一个浏览器,加载一个登录页面如何获取用户名和密码框 在Android中写一个浏览器,记住密码功能怎么写?大神,请指教. 解决方案 webview加载你的登录页面,登录完了后取cookie或其他认证信息(这个和你登录的网站是如何设计的有关) 解决方案二: 用webview 啊 解决方案三: 用sharedpreference来保存密码或者是账号 解决方案四: 这两个输入框是浏览器的还是网页的?

做一个登录页面 用的是springMVC+mybatis 怎么做?

问题描述 我已经做好了后台的页面一些增删改查也都做好了现在希望做一个顾客版本的首先需要登录进去之后是个人中心请问那个登陆怎么做.ps.已有一个登录这个还有权限方面的问题.小白一个,希望各位大神给我一个思路.愁死了 解决方案 解决方案二:权限方面可以参考rbac:解决方案三:可用springsecurity,你用spring用这个是非常合适的解决方案四:功能表,角色表,用户表,互相关联,通过用户查角色,通过角色查对应的功能,通过功能在页面上显示功能菜单.解决方案五:http://download.

Swift 自动布局库SnapKit的实现一个登录页面使用详解

前面的几篇文章讲解了自动布局库SnapKit的使用方法.本文通过一个完整的样例(登录页面)来演示在实际项目中如何使用SnapKit来实现自动化布局的. 1,效果图如下 2,代码讲解 (1)用户名.密码输入区域(白色区域)设置垂直居中约束,其高度是固定90,宽度自适应(距离屏幕左右侧都为15像素) (2)用户名.密码输入框之间分割线是使用灰色背景的UIView实现,其高度是1像素,同样设置垂直居中约束. (3)登录按钮距离上方输入区域20像素,高度固定是40,宽度同样自适应(距离屏幕左右侧都为15

[Js插件]使用JqueryUI的弹出框做一个“炫”的登录页面

引言 查看项目代码的时候,发现项目中用到JqueryUi的弹出框,可拖拽,可设置模式对话框,就想着使用它弄一个登录页面. 弹出框 在Jquery Ui官网可定制下载弹出框,下载和弹出框下载相关的js文件,css文件. 官方网站:http://jqueryui.com/ 项目结构:   Login.html 引入文件: 1 <link href="Scripts/css/redmond/jquery-ui-1.10.4.custom.css" rel="styleshee

springmvc-用jsp写一个简单的登录页面

问题描述 用jsp写一个简单的登录页面 求写一个登录页面,有form表单,然后能提交到数据库.框架是spring,数据库是sql,用java,jsp写..我是新手,所以恳求大神帮帮我.非常感谢谢.. 解决方案 form表单里面放输入框组,用于填写数据,像登陆这种涉及隐私的操作,最好使用post方式提交, 在action层,我看到你只提到了spring,那就直接servlet来接收数据进行处理,在doPost中通过request.getParameter(str)获取参数,经过一系列校验之后,就可

优秀WEB登录页面设计

  从公共平台的角度看 用户活跃度是检验产品成功与否的重要指标之一,传统行业的商家极为重视门面的装潢,因为一个好的门面可以聚集人气,招揽更多的顾客.古时候的大户人家院子门口的石狮子或其他的摆件的摆放极为讲究,有一定的风水学说道理,更能彰显主人家的身份地位.由此可见,"门面'就如人的脸面之于人的形象一样重要,而WEB的登录页面就相当传统的"门面". 从个人博客的角度看 个人登陆页面一般只有自己会用到,所以别人基本是看不到的,但也不排除像我一样无聊什么都好奇的人存在,什么都想看看