web控件开发系列(四) 自定义控件属性(下)

控件在WEB开发时经常要用到,虽然有部分已经存在工具箱里,但有时总需要根据自己的要求,开发一些合适自己的控件。接上一节,已经说过了控件的属性, 例如,我们需要一组属性的集合时,这时我们需要用到的就是复杂属性了,简单的属性满足不了我们的要求,例如:大家熟悉的字体信息设置那栏。下面为大家介绍一下实现的几种代码与注意细节

一、连字符形式的复杂属性标记
<asp:Button ID="Button1" runat="server" Font-Bold="True" Font-Italic="True" Font-Names="Arial" Font-Overline="True" Font-Size="20pt" Text="Button" />
例如上面就是一个Font的复杂属性,通过这个属性可以设置一系列相关的值。
在ServerControl中添加一个类ComplexAttribute,然后输入下面代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;


namespace ServerControl
{
    [DefaultProperty(
"Text")]
    [ToolboxData(
"<{0}:ComplexAttribute runat=server></{0}:ComplexAttribute>")]
    
public class ComplexAttribute: WebControl 
    {
        
private Student _student;

        
public ComplexAttribute()
        {
            _student 
= new Student();
        }        

        [Description(
"Student属性")]
        [Category(
"Student属性")]
        [PersistenceMode(PersistenceMode.Attribute)]   
//指定如何将服务器控件属性或事件保持到ASP.NET页面的元数据属性
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]  //指定属性是否以及如何在代码中序列化
        [TypeConverter(typeof(ExpandableObjectConverter))]  //指定用作此特性所绑定到的对象的转换器的类型
        [NotifyParentProperty(true)]
        
public Student Student
        {
            
get 
            {
                
if (_student == null)
                {
                    _student 
= new Student();
                }
                
return _student;
            }
        }

        
/// <summary>
        
/// 输出控件
        
/// </summary>
        
/// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write(
"姓名:");
            writer.Write(_student.Name);
            writer.WriteBreak();
            writer.Write(
"年龄:");
            writer.Write(_student.Age.ToString());
            writer.WriteBreak();
            writer.Write(
"分数:");
            writer.Write(_student.Cost.ToString());
            writer.WriteBreak();
        }

    }

    
/// <summary>
    
/// 密封类,封装文本的字体属性。无法继承此类。
    
/// </summary>
    public sealed class Student
    {
        
private string _Name = "Name";
        
private int _Age = 0;
        
private int _Cost = 0;
        [NotifyParentProperty(
true)]   //这个是为了实现在属性窗口中更新属性值时将通知其父属性,不然修改了属性窗口的值,但不通知你属性,等于没修改
        public string Name
        {
            
get { return _Name; }
            
set { _Name = value; }
        }
        [NotifyParentProperty(
true)]
        
public int Age 
        {
            
get { return _Age; }
            
set { _Age = value; }
        }
        [NotifyParentProperty(
true)]
        
public int Cost 
        {
            
get { return _Cost; }
            
set { _Cost = value; }
        }
    }
}

注意细节,不然你会感觉到很多地方不明白:
1、Student类,在设计时最好封装起来,添加密封限制,让这个类无法继承。
2、Student类的属性添加特性[NotifyParentProperty(true)]
3、构造函数ComplexAttribute时初始化Student类,不然设计器中你的控件会出现未引用对象的错误提示。
4、ComplexAttribute类的属性添加特性[PersistenceMode(PersistenceMode.Attribute)]   //指定如何将服务器控件属性或事件保持到ASP.NET页面的元数据属性
5、ComplexAttribute类的属性添加特性[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]  //指定属性是否以及如何在代码中序列化
6、ComplexAttribute类的属性添加特性[TypeConverter(typeof(ExpandableObjectConverter))]  //指定用作此特性所绑定到的对象的转换器的类型
7、ComplexAttribute类的属性添加特性[NotifyParentProperty(true)]

PersistenceMode详解:
指定如何将服务器控件属性或事件保持到ASP.NET页面的元数据属性,共存在4种枚举设置方式:
1、PersistenceMode(PersistenceMode.Attribute)指定属性或事件保持为属性;
2、PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)指定属性作为服务器控件的唯一内部文本,如果属性值是HTML编码的,只能对字符串作这种指定;
3、PersistenceMode(PersistenceMode.InnerDefaultProperty)指定属性在服务器控件中保持为内部文本,还指示将该属性定义为元素的默认属性,只能指定一个属性为默认属性;
4、PersistenceMode(PersistenceMode.InnerProperty)指定属性在服务器控件中保持为嵌套标记,通常用于复杂对象,它们具有自己的持久性属性。
DesignerSerializationVisibility详解:
指定属性是否以及如何在代码中序列化,其值为DesignerSerializationVisibility的枚举值,存在3种设置方式:
1、DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)指定序列化程序不应该序列化属性值;
2、DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)指定应该允许序列化程序序列化属性的值;
3、DesignerSerializationVisibility(DesignerSerializationVisibility.Content)指定序列化程序应该序列化属性的内容,而不是属性本身。此字段为只读。Visible为其默认值。

编译,在页面上拖进控件,再看一下属性窗口,你自己定义的属性就在里面了,如下图:


设置Student属性,到页面代码视图,就会出现下面的代码:
 <cc1:ComplexAttribute ID="ComplexAttribute1" runat="server" Student-Age="10" Student-Cost="95" Student-Name="ASP.NET" />

二、内部嵌套复杂属性标记

<asp:GridView ID="GridView1" runat="server">
    <RowStyle BackColor="#EFF3FB" />
</asp:GridView>
例如上面的代码,BackColor属性RowStyle是内部嵌套。
在ServerControl中添加一个类InRowAttribute然后输入下面代码:

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace ServerControl
{
    [DefaultProperty(
"Text")]
    [ToolboxData(
"<{0}:InRowAttribute runat=server></{0}:InRowAttribute>")]
    [ParseChildren(
true), PersistChildren(false)]
    
public class InRowAttribute : CompositeControl
    {
        
private Style _Style;

        
public InRowAttribute()
        {
            _Style 
= new Style();
        }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [NotifyParentProperty(
true)]
        [Category(
"复杂属性")]
        [Description(
"复杂属性——内部嵌套形式")]
        
public Style BackColorStyle
        {
            
get
            {
                
if (_Style == null)
                {
                    _Style 
= new Style();
                }
                
return _Style;
            }
        }

        
/// <summary>
        
/// 输出控件
        
/// </summary>
        
/// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write(_Style.BackColor.ToString());
        }

    }

    [TypeConverter(
typeof(ExpandableObjectConverter))]  
    
public class Style
    {
        
private Color _BackColor;

        [NotifyParentProperty(
true)]
        
public Color BackColor
        {
            
get { return _BackColor; }
            
set { _BackColor = value; }
        }

    }
}

编译后在设计器中拖进这个控件,在属性窗口设置值,在代码视图中可以看到下面的代码
<cc1:InRowAttribute ID="InRowAttribute1" runat="server">
    <BackColorStyle BackColor="ActiveBorder"></BackColorStyle>
</cc1:InRowAttribute>

属性定定义方面还有好多类型,例如我们常用的ListItem组合, CheckBox组合, 或自己需要时定义的边框线条,边框大小,颜色等等,这些都是大家在开发中慢慢摸索(举一反百)吧,如果大家有好的控件,不防也与我分享一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值