今天你写控件了吗?----ASP.net控件开发系列(三)

属性全接触(一)

本系列上篇文章有几位抬爱,鼓励了几句,所以劲头又足了,这不,这篇文章就出得快了,:)
希望能继续得到鼓励和指正。
这次我们来探讨下控件开发中的属性设计的方方面面,属性本是各种.net下语言的最基本语法,但控件做为一种提供给程序员二次开发的发布件,其功能的强大与使用的灵活都离不开良好的属性设计,所以我觉得属性设计是控件开发中第一座要打下的堡垒。
首先我们来看一段.aspx文件中的HTML样式的代码:

<asp:DropDownList id="DropDownList1" runat="server" Font-Bold="True">
 
<asp:ListItem Value="1">1</asp:ListItem>
 
<asp:ListItem Value="2">2</asp:ListItem>
</asp:DropDownList>


 

这种代码大家都写过无数次了,不过,现在我们要从另一种角度来分析这段代码:
DropDownList控件在和用户交互时,它没有把它的属性一股脑放在一起来表示出来,而是分为以下几种情况:
1.像ID、Runat、Font-Bold这些,放在<>标记里;
2.Font-Bold不同于其它,它有一个短横分隔成两部分,这种表示方式不是Font-Bold是一个属性的名称,而是说明它是一个子属性,是Font属性(Font类)的Bold属性,对应.cs文件的写法是:Font.Bold;
3.ListItem放在了DropDownList的一双<>标记的中间,而不是标记之类,同样1、2也放在了ListItem的中间。
下面我们来分别看看这几种属性记录方式是怎么实现的。
有一个Attribute来做这件事件PersistenceMode(System.Web.UI.PersistenceModeAttribute)。
它有以下几个值供选择:
Attribute(default)属性保存在控件的标签里;默认值
EnCodedInnerDefaultProperty 属性是编码的HTML,放在控件标签对的中间保存,以上的ListItem就是这样保存Text属性的(1、2);

[PersistenceMode(PersistenceMode.EnCodedInnerDefaultProperty)]
public string Text
{
 
}


InnerDefaultProperty 属性保存在控件标签对的中间,以上的DropDownList控件的Items属性就是这样保存的(就是那堆ListItem);

[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public ListItem Items
{
 
get
 
{
  
 }

}


InnerProperty 属性和其它属性一起保存为控件标签对中的嵌套内容,DataGrid用这种方式把一堆东西包在标签里,这时,属性要用标签声明,内含属性值。

[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual TableItemStyle ItemStyle
{
      
get
      
{
            .
      }

}


第二个议题,属性的持久性
众所周知,网页是基于无状态机制的,就是说,页面Response后就不管理保存页面内容的状态,ASP.net提供ViewState机制来保存页面的状态,ViewState是实现方式是送出页面中的一个名为__ViewState的input type='hidden',也就是说它和Session不同,它保存在页面中......不废话了,反正我们要保存控件的状态(就是它的各个属性),而不至于在回传的过程中丢失,我们采用的方案就是ViewState,下面简单的举个例子说明ViewState在Property中的用法

  [
  DefaultValue(
2),
  TypeConverter(
typeof(Int32Converter)),
  Category(
"Behavior"),
  Description(
"Duration of complete once transition.(s)"
  ]
  
public int Duration
  
{
   
get
   
{
    
object b = ViewState["Duration"];
    
return (b==null)?2:(int)b;
   }

   
set
   
{
    
if(value < 1)
    
{
     
throw new ArgumentOutOfRangeException("Duration");
    }

    ViewState[
"Duration"= value;
   }

  }


像这种方式直接使用ViewState是最简便的,我们不必改写LoadViewState、SaveViewState方法,至于怎么自定义ViewState管理,在后面的文章中将有介绍。

关于属性的东西太多了,这次就写到这,下篇将写写怎样订制属性与IDE的交互。

posted @ 2005-05-10 08:56 Think 阅读(9932) 评论(19) 编辑 收藏

 回复 引用   
#1楼2005-05-10 11:09 | xo
不错,说的正是我想知道的东西
 回复 引用   
#2楼2005-05-10 11:23 | 木鱼。NET
建议可以写一个控件实例如:菜单、复合控件,一步一步加功能,针对功能讲解属性,样式,事件,回传机制等控件开发技术,这样对初学者也明白控件开发的流程,理解更深刻一些,在这一过程中大家可以提出自己的想法,积极参与使控件更成熟,更完善!
 回复 引用 查看   
#3楼[楼主]2005-05-10 11:30 | 仁渣      
你的建议不错,其实我也想过这种方式,不过,我想把实例这个过程放到介绍完所有的知识重点再做,一则我还没有想到合适的开发实例能贯穿始终,再则,每篇加上实例,会使文章增肥,要知道写这么点文字也是很要时间的,我不像吕震宇老师,可以直接把工作中的教案、课件拿出来,我写这些东西是白天写了一天代码,晚上赶出来的,所以质量、数量都不会在那样的高度。请见谅。
一般回家后,做饭、洗澡、再写个BLog就11点了。

 回复 引用   
#4楼2005-05-10 11:41 | 木鱼。NET
是啊,选择一个实例贯穿始终的确是件麻烦的事情,况且还要坚持写完,还能够给大家以帮助,难度更大了,希望你能坚持下来,我会继续关注的,当然也会发表一下自己的看法,不要见怪啊!
问一下,你回家怎么还要做饭啊,怎么跟我一样悲惨!

 回复 引用 查看   
#5楼[楼主]2005-05-10 11:48 | 仁渣      
这不是没女朋友嘛(有了也要是勤快才行,勤快还要会做饭才行,我嘴刁)
 回复 引用 查看   
#6楼[楼主]2005-05-10 11:49 | 仁渣      
呵呵,像上面我找的例子都尽量是大家都熟悉的控件的,就找这个都要花点精力的。
 回复 引用   
#7楼2005-05-10 11:56 | 木鱼。NET
理解!
 回复 引用   
#8楼2005-05-10 11:58 | 刘力文
问一下,你回家怎么还要做饭啊,怎么跟我一样悲惨!

怎么我也一样呀,每天还要买菜,做饭,悲哀.

 回复 引用 查看   
#9楼[楼主]2005-05-10 12:01 | 仁渣      
我只做菜就行,我有个兄弟专门负责做饭,买办所以东西,哈哈。
 回复 引用   
#10楼2005-05-10 21:08 | CsOver
有时觉得一天二十四小时太少了呢。
 回复 引用   
#11楼2005-05-13 17:29 | james[未注册用户]
想看园主的RevealTransitionImage1的源码,学习自定控件,不知楼主能否割爱。
james@lfnc.com.cn

 回复 引用   
#12楼2005-05-13 21:09 | mzl
写的非常好,太棒啦!
 回复 引用 查看   
#13楼[楼主]2005-05-14 09:02 | THIN(仁与渣)      
[ 发送成功 ]

您已经成功将信直接转交到: james@lfnc.com.cn


 回复 引用   
#14楼2005-05-24 21:11 | 喜欢雨
辛苦了
谢谢你所做的工作...

 回复 引用   
#15楼2005-09-07 11:15 | Jeky[未注册用户]
老大,我写了一个简单的控件,可是拖到vs.net中却发现属性没有默认值。
我是这样写的,哪儿出错了:

[
DefaultValue("正在加载"),
TypeConverter(typeof(StringConverter)),
Category("Appearance"),
Description("文本提示语。")
]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}


我奇怪的是,string类型的属性没有默认值。而int、bool之类的属性默认值都可以显示。不知道怎么回事儿?

 回复 引用 查看   
#16楼[楼主]2005-09-07 11:19 | THIN      
int 和 bool 都有默认值
你应该这样写
public string Text
{
get
{
if(text == null || text == string.Empty)
text = "正在加载";
return text;
}
}

 回复 引用 查看   
#17楼2005-11-30 13:38 | Colin Han      
支持一下!
正想学习一下WEB Control呢。

 回复 引用   
#18楼2008-08-11 11:17 | 似水骄阳[未注册用户]
支持一下,正想学习开发控件方面得知识!
 回复 引用 查看   
#19楼2009-12-07 23:36 | 蔷薇      
2005年的我再看,,,,汗。。。