Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > .NET > VB.NET > asp.net控件开发基础(9)
【标  题】:asp.net控件开发基础(9)
【关键字】:asp.net
【来  源】:http://www.cnblogs.com/Clingingboy/archive/2006/09/14/502930.html

asp.net控件开发基础(9)

Your Ad Here asp.net控件开发基础(9) - Clingingboy - 博客园

Clingingboy

专注于Web开发

博客园 首页 新随笔 联系 聚合 管理
  49 Posts :: 0 Stories :: 152 Comments :: 3 Trackbacks
        上一篇讲了复合控件的基础知识,本来接着要继续讲复合控件样式的使用,让我们暂时回到前面第五篇的时候,继续讨论关于属性方面的一些知识.

写第五篇的时候,我一步步的加上元数据(特性),使得设计时效果更加好,如对复杂属性应用以下特性,使属性浏览器支持扩展/折叠效果,使你更加容易编辑子属性,但接着我又遇到了问题,所以必须去解决

1.认识默认属性浏览器支持

让我们再认识一下属性,大家知道每个属性都是有类型的,最熟悉就是string,int这些类型了,vs2005属性浏览器对这些属性类型进行了识别,
如下例子

(1)table控件的Height属性,当你设置属性为字符串时,则提示错误信息



(2)当属性类型为Color属性时,属性浏览器为你提供颜色选择器



(3)当属性类型为枚举类型时,属性浏览器则支持下拉框选择




(4)当类型是时间类型,属性浏览器则支持时间选择器



通过上面,我们认识到属性浏览器默认会判别属性类型,当属性值跟属性类型不符时,则会提示错误信息.这里我们还认识到属性浏览器默认为一些属性类型提供了便利

2.属性表现形式的多样性


在定义控件属性时,可以直接这样定义,属性都为字符串形式

<asp:TextBox ID="TextBox1" runat="server" 
        Height
="11" BackColor="Blue" 
        ForeColor
="#FF8000">测试</asp:TextBox>

用代码表示则是这样,在后台代码中定义的属性类型必须相对应,BackColor必须为Color类型,否则则会出错,当在页面呈现时,则以字符串形式呈现.
    
protected void Page_Load(object sender, EventArgs e)
    
{
        
//TextBox1.BackColor = "blue";
        TextBox1.BackColor = System.Drawing.Color.Red;
        TextBox1.BackColor 
= System.Drawing.Color.FromName("blue");
    }


通过上面,我们认识到属性类型需要转换,这里便要引出我们所要讲的话题,类型转换器.

例如,当BackColor="Blue" 时,则会激活一个类型转换器实例将字符串值转换成声明的类型(即将"blue"转换成Color类型,然后赋给BackColor.

.net类库中的基本类型和许多类型都有与其相关联的类型转换器.

一般常用的类型有String,Int,Boolean,DateTime,Enum等类型,其类型已默认与其相对应的类型转换器关联起来.



Color类默认关联的类型转换器System.Drawing.ColorConverter

FontInto类默认关联的类型转换器System.Drawing.FontConverter

类型转换器的基类为System.ComponentModel.TypeConverter,所有的类型转换器都从其派生.


下面我们再来看一个例子,

我们先定义一个复杂属性,用于测试

示例一


再看aspx文件

其中我们输出了Label的几个属性,包括FontInfo这个复杂属性,并且实例化了上面定义的Name类


下面看看输出结果,如下图



结果是将FontInfo属性和Color属性转换成字符串形式呈现,而我们自定义的Name属性只以其类型呈现,并未呈现其子属性值.
再来看看第一点默认属性浏览器支持和第五篇我们所定义的一个复杂属性CustomComponents.Address,
CustomComponents.Address属性同样存在着这样的问题,再对比一下FontInfo属性在属性浏览器的支持,如下图



---------------------------------------------------------------------------



复杂属性CustomComponents.Address无法编辑,只读,而且显示的是其属性类型.
复杂属性Font则默认显示了子其属性的值(其默认只显示Names值和Size值,且为只读)

问题来了,我们要根据需要为自定义属性实现类型转换器.

3.自定义属性类型转换器

上面已经说明问题所在了,实现类型转换器,可以将属性类型和字符串类型之间相互转换.

下面我们就为解决这个问题而来了解类型转换器,我们还是以第五篇的那个例子来学习

在说第二点属性表现形式的多样性的时候已经说过了

类型转换器的基类为System.ComponentModel.TypeConverter,所有的类型转换器都从其派生.

下面以第五篇时的例子为基础

我们为Address实现了一个类型转换器,其实现了复杂属性代码的折叠,如下代码

[TypeConverter(typeof(ExpandableObjectConverter))]
    
public class Address
    
{
}

System.ComponentModel.ExpandableObjectConverter 类也是从TypeConverter类派生
所以当自定义复杂类型的类型转换器时,则可从ExpandableObjectConverter 类派生
如果你定义的属性不是复杂属性,则可以直接从TypeConverter类派生

(1) 值翻译的类型转换器

从TypeConverter类派生的自定义类型转换器则需要重写TypeConverter类几个方法,主要目的就是实现自定义属性类型与字符串值之间的转换.

你需要了解以下几个方法,这里我们就以Address属性为例子,这样来解释以下方法更好理解.

其实可以理解成一来一去的关系,Form,To,相互之间的转换,如下代码:

TypeDescriptor类的方法为静态方法,通过GetConverter方法获取类型转换器
然后通过TypeConverter类的ConvertFromString方法和ConvertToString相互转换类型.

示例二


自定义好类型转换器后,要与属性相关联起来

    [TypeConverter(typeof(AddressConverter))]
    
public class Address
    
{
        
        
public Address()
            :
            
this(String.Empty, String.Empty,
            String.Empty, String.Empty)
        
{ }

        
public Address(string street, string city,
            
string state, string zip)
        
{
            
this.street = street;
            
this.city = city;
            
this.state = state;
            
this.zip = zip;
        }
          .......
    }


下面来看下效果,如下图,属性编辑器显示的CustomAddress不再显示其类型了,已将其转化为字符串形式了,如果你设置CustomAddress可写的话,就可以直接编辑CustomAddress属性,但其只有四个子属性,所以当大于5个时就会出错,且格式也不可以乱改,一般情况下都设置其只读.


为了在页面上显示这个CustomAddress属性,还需要为Address类重写一下ToString方法,如下代码

        方法