重新画差不多一摸一样的UI? - ASCX的MVC模式实现

转载 2006年06月04日 21:01:00
[摘要]
本文论述了如何改善设计,使表层的结构更灵活。

[引言]
前几天, 我在与一个朋友, 他同时是我的技术经理,谈到我所设计的ASCX基本实现了MVC的时候, 他好像显得特别不以为然。他说ASP.NET本来就是MVC分开的。ASPX就是V,而CODE BEHIND就是C,数据库就是M。我想他没有真正理解我的意思。

确切地说我也不清楚自己到底有没有正确理解MVC。我想如果要像理解数学或者几何原理一样理解也不是必要的。能够解决实际问题的、灵活的、易于维护的设计就是好的设计。

[实例]
为了更明白地说明问题,或者为了减小篇幅,我引入一个实际应用中非常普遍的需求:管理会员。每个会员到系统中注册,我们想尽可能知道他的资料。我们需要一个模块来管理会员的基本资料,诸如姓名,年龄,个人爱好,联系办法种种。我们需要收集这些资料,管理员需要查询这些资料,用户自己也许会修改这些资料。这其中必须我们提供数个界面来协助用户操作。

V
这里的V是ASCX构图。大家都知道ASCX即可以显示HTML,又可以直接查询数据库,又可以做计算。可以包容任何服务器端控件。但是好的设计的原则是“高内聚,低耦合”,ASCX归根到底是一个类。我们不能设计得让它无所不能,或者说让它知道我们太多业务上的逻辑。比如数据库是如何设计的, 底层类都有那些方法。一种对象,不管其内部逻辑多复杂,其公开的特性或者方法越少越好,越常规越好。那么我们给ASCX都设计什么功能呢?

这里,我们将ASCX看作消极的显示数据的”白板“。仅仅被动到通过控制器设置其属性呈现数据。而有关数据的处理一概不管。当然,我们的白板也不见得就是白色的。在格式上还是允许它尽可能玩出花样。对于我们的实例,我们设计了一种ASCX来呈现会员基本资料。MemberInformation.ascx(MemberInformation类)。我们需要给类MemberInformation公开一系列特性。比如我们要求白板上显示姓名,出生日期,电话,电子邮件...,我们就需要给类MemberInformation公开Name, BirthDate, PhoneNumber, EmailAddress等特性。在显示构图方面,我们需要以集中模式将数据呈现出来
1.查询时只读显示
2.新会员登记填空表单
3.会员更改个人资料时的表单
至少会有以上几种情况。这些视图,显示的数据是完全一样的,而表现模式又大大不同。如果我们直接把上述界面制作在ASPX页上,我们不得不设置显示单条数据个一个个服务器对象的值。还有复杂的有效性验证。

将以上视图合一。
既然数据一致,并且多处使用,就有封装的必要。我们将上述视图总结一下,不外乎:以HTML表单形式展示数据,以报表的方式展示(只读)。不论是新登记还是老会员更改资料。我们必须是ASCX这个V层可以以两种方式展现相同的数据方案。

两种表现模式
我们需要以HTML ATTRIBUTE或者编程的方式控制ASCX的表现模式。我们给MemberInformation类设置一个属性:public string PresentationMode.之所以是串类型是因为需要在HTML ATTRIBTE中设置。可选的值有Form,(可输入数据的表单模式),Report模式(只读的报表模式)。这样我们可以像如下的方法控制其表现模式:
<Xxx:MemberInformation ID=MemberInformation1 Runat=Server PresentationMode=Form />
也可以在编程时像如下方法:
this.MemberInformation1.PresentationMode = “Form“;

设置FORM值时,ASCX显示出来就是表单样式了。

如何让ASCX这么听话呢
在ASCX里放置两个<asp:Panel />一个内装一个HTML table, 按照既定的格式排列各个服务器control. 另一个装安排好的form elements. 呈现时(一般是Page_Load控制)检查自己的PresentationMode值,如果是form就显示第一个panel, 隐藏第二个。如果设置为Report则相反。这样看起来ASCX就可以切换界面了。
代码范例(实际项目摘取)
  /// <summary>
  /// 关键特性: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
  /// Form: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  /// Report: xxxxxxxxxxxxxxxxxxxxxxxx
  /// 缺省值: Form
  /// </summary>
  private string representationMode = "Form";
  public string RepresentationMode
  {
   get
   {
    return this.representationMode;
   }
   set
   {
    this.representationMode = value;
    if(value == "Form")
    {
     this.FormPanel.Visible = true;
     this.ReportPanel.Visible = false;
    }
    else
    {
     this.FormPanel.Visible = false;
     this.ReportPanel.Visible = true;
    }
   }
  }


与公开的特性连接
公开的特性是其控制器访问或设置视图的数据的接口。一般通过编程进行设置。既然是公开的特性就必须有get,set访问器。这些特性的访问器必须即可以设置到report的数据,又可以访问到form的数据。总之,特性访问器一般必须很清楚地知道管姓名的是哪两个,管年龄的又是哪两个。这样,我们只需设定MemberInformation1.Name = “Jay Xu“, MemberInformation1.Age = 23就可以了。 而不用管显示姓名的控件被安排在什么地方,名称或ID是什么。

特性有关代码范例(实际项目摘取)
  /// <summary>
  /// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  /// xxxxxxxxxxxxxxxxxxxxxxxx
  /// </summary>
  public string Name
  {
   get
   {
    return this.NameBox.Text;
   }
   set
   {
    this.NameBox.Text = value;
    this.NameLabel.Text = value;
   }
  }


数据模型统一。
这里的M,其实是一系列常规值的组合。例如姓名(字符串),年龄(整型),出生年月日(日期)等。在作者实际的项目中,数据实体是一组派生自DataSet的强类型化了的对象。所以并没有将这些数据打包成一个类。

控制器
控制器是管理ASCX的容器。对MemberInformation的数据进行写入,读出的工作。设计到数据是怎么从数据库到前端来的,还有数据是如何持久化到数据库中去的,都是控制器应该操心的事情了。我们的V只管显示数据,还有听从安排切换模式。

[进一步增强]
在get, set访问器中进行有效性校验。例如日期的有效性。可以在get访问过程中进行计算。如果出错,可以选择抛出异常,或者以某种形式通知用户。这些逻辑都应该隐藏在ASCX。
为适应不同场合需求,可以给ASCX增加多个用于控制样式的特性。例如背景色,字体,等等。

[需要注意的问题]
如果某些值是通过在有限项中选择得到的, 则应通过一定途径给选择控件赋初值。如果某些值是多项选择的,则应以合适的数据类型表现其值,比如数组。
在使用编程的方式切换显示模式时注意应使控件的EnableViewState属性为true.(缺省值就是true, 只要你不显示地关闭它)。


[设计思想上的扩充]
可以将这个设计思路应用到其他类型的ASCX上. 比如用于显示List(名单)样式的数据时. 可以把已经设计好的Repeater或者DataGrid包装成一个ASCX.

如果你明白了本文意图, 你可以在你的下一个项目中尝试一下, 编码的工作量可能会稍微增加, 但是除了可以很好的解决当前的问题外, 在一定程度上使设计工作更灵活, 更优雅, 并且带来重用的可能. 也能为将来的项目提供帮助.
FROM:http://xchunyu.cnblogs.com/archive/2004/04/08/5475.html

ASP.NET MVC加载ASCX后并获取其内控件值或赋值

有网友看了这篇《ASP.NET MVC加载ASCX之后,并为之赋值》http://www.cnblogs.com/insus/p/3643254.html 之后,问及Insus.NET,不想在控件制器...
  • linybo
  • linybo
  • 2015年04月06日 20:08
  • 701

Unity3d中UI开发的MVC模式

原文:http://engineering.socialpoint.es/MVC-pattern-unity3d-ui.html 动机         和游戏开发的其他模块类似,UI一般需要通过多次迭...
  • jjiss318
  • jjiss318
  • 2015年03月12日 13:58
  • 21458

unity3d MVC设计模式

 动机         和游戏开发的其他模块类似,UI一般需要通过多次迭代开发,直到用户体验近似OK。另外至关重要的是, 我们想尽快加速迭代的过程。使用MVC模式来进行设计,已经被业界证明了是...
  • qq_27361571
  • qq_27361571
  • 2016年03月02日 14:22
  • 702

基于MVC架构写一个UI框架

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织...
  • lovethRain
  • lovethRain
  • 2016年08月19日 12:23
  • 2001

在用户控件(ASCX)创建用户控件(ASCX)

"我建了两个ascx,ascxA,ascxBascxA中放了一个PlaceHold,ascxB中放了一个textBoxascxA在page_load中动态创建了5个ascxB但是页面上什么都没显示"这...
  • dyllove98
  • dyllove98
  • 2013年06月22日 22:19
  • 12296

Struts2实现MVC(概念解析)

框架简述 什么是框架:框架就是能完成一定基础功能的半成品软件。在没有框架时,所有的工作都要从最底层做起;但是有了框架后,它可以为我们提供一定的基础功能,我们就可以在框架的基础上进行开发,而无需自己去实...
  • a_good_programer
  • a_good_programer
  • 2016年09月07日 20:45
  • 643

我理解的软件 架构模式,MVC和分层

缘起:作为程序员,很容易天天被业务追逐着,抽不开时间修炼。有一天突然停了一下,忽地就会有一种怅然的感觉,过去的那些日子我学到了什么? 有人很认真地说自己有10年经验,有人笑说你不过是一年经验用了10年...
  • vshuang
  • vshuang
  • 2016年12月03日 00:22
  • 1502

MVC模式 重新理解

from  MVC模式理解——当年给我一个browser多好 以前一直无法舒坦的理解,MVC模式是怎样实际应用到一个程序上的。 这两天因为工作google出一幅图,然后恍然大悟。 图1...
  • zlj_fly
  • zlj_fly
  • 2014年12月02日 20:10
  • 448

MVC设计模式:Struts的Action思想

Struts实质就是MVC模式的体现;因为它强制把程序分成三层结构,大大提高了灵活性,使得程序更加利于开发、扩展和维护。 MVC包含三个基础部分:Model、View和Controller,这三...
  • qq_23865789
  • qq_23865789
  • 2016年07月16日 16:35
  • 1178

Struts2概述与MVC模式

truts分为两个主要版本,struts1和struts2,struts2是由webwork2发展而来的 1、Framework概念:将相同类型问题的解决途径进行抽象,抽取成为一个应用框架。这就是F...
  • IT_LOSER
  • IT_LOSER
  • 2016年10月13日 14:13
  • 1152
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:重新画差不多一摸一样的UI? - ASCX的MVC模式实现
举报原因:
原因补充:

(最多只允许输入30个字)