当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > ASP.NET2.0服务器控件之创建复杂属性

ASP.NET
asp.net GridView控件中模板列CheckBox全选、反选、取消
asp.net GridView 删除时弹出确认对话框(包括内容提示)
asp.net DropDownList 三级联动下拉菜单实现代码
asp DataTable添加列和行的三种方法
Asp.net 页面调用javascript变量的值
asp.net 长文章通过设定的行数分页
asp.net 定时间点执行任务的简易解决办法
asp.net 页面延时五秒,跳转到另外的页面
asp.net 动态输出透明gif图片
asp.net DataList与Repeater用法区别
asp.net Javascript获取CheckBoxList的value
asp.net程序在调式和发布之间图片路径问题的解决方法
asp.net下生成英文字符数字验证码的代码
asp.net 页面版文本框智能提示JSCode (升级版)
ASP.NET URL伪静态重写实现方法
ASP.NET 2.0 中Forms安全认证
asp.net 动态添加多个用户控件
asp.net Repeater显示父子表数据,无闪烁
asp.net 无法获取的内部内容,因为该内容不是文本 的解决方法
asp.net GridView排序简单实现

ASP.NET2.0服务器控件之创建复杂属性


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 78 ::
收藏到网摘: n/a

本文详细讲解了一个利用ASP.NET 2.0技术创建复杂属性的示例。

1、示例应用

本文所实现的示例很简单,其核心是通过实现自定义服务器控件的连字符形式复杂属性来说明复杂属性的实现方法,其中使用了上一篇文章中介绍的内容。

页面显示了公司所在城市、姓名、性别和职务信息。这些内容是定义服务器控件呈现的结果,其中公司所在城市由简单属性City设置,姓名、性别和职务由复杂属性Employee设置,其中包括子属性Name,Sex和Title设置。下面列举了示例应用程序的Default.aspx文件源代码。

以下为引用的内容:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Namespace="WebControlLibrary" Assembly="WebControlLibrary" TagPrefix="Cp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>实现连字符形式复杂属性</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<Cp:Company ID="demo1" runat="server" City="重庆" Employee-Name="小李" Employee-Sex="男" Employee-Title="销售经理" />
</div>
</form>
</body>
</html>

如上代码所示,主要设置了@ Register指令和自定义服务器控件Company。前者用于为页面引入自定义服务器控件Company,从而实现控件在页面中的应用。在自定义服务器控件Company中主要设置了City、Employee-Name、Employee-Sex和Employee-Title。同时,在开发人员编码过程中将会发现,以上4个属性均为Visual Studio 2005的智能感知功能所支持。

另外,读者还可以以另一种非连字符形式设置Company控件属性。具体代码如下所示:

以下为引用的内容:
<Cp:Company ID="Company1" runat="server" City="重庆">
<Employee Name="小李" Sex="男" Title="销售经理">
</Employee>
</Cp:Company>

实际上,以上设置Company控件属性的方法与前文利用连字符设置属性的方法是完全一致的。对于所有连字符形式属性,可以任意使用二者之一。如果是基于代码可读性的角度而言,后者比前者的可读性更强一些。

2、实现方法

上一小节中的Default.aspx页面所包含的Company控件具有3个连字符形式复杂属性。它们是如何实现的呢?实际上,实现这种形式的复杂属性关键是,在自定义服务器控件实现过程中,对复杂属性及其子属性设置特定的设计时元数据。

对于复杂属性而言,主要在该属性实现前设置两个设计时元数据:DesignerSerializationVisibility和NotifyParentProperty。DesignerSerializationVisibility用于指定在设计时序列化组件上的属性时,所使用的持久性类型。NotifyParentProperty可使得属性浏览器中对子属性的修改通知一直上传到对象模型,并在被修改了子属性的控件中产生修改通知。对于子属性的设计时元数据设置比较简单,只需在子属性实现前设置一个NotifyParentProperty即可。

实现自定义服务器控件Company涉及两个文件:Company.cs和Employee.cs。前者是自定义服务器控件的实现主体,其中包括各种属性设置、控件呈现方法RenderContents等等。后者用于实现复杂属性Employee。下面首先列举了Company.cs文件源代码。

以下为引用的内容:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary{
 [DefaultProperty("Text")]
 [ToolboxData("<{0}:Company runat=server></{0}:Company>")]
 public class Company : WebControl {
  private Employee employee; //实现属性City
  [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("公司所在城市") ]
  public string City {
   get {
    string _city = (String)ViewState["City"];
    return ((_city == null)?String.Empty:_city);
   }
   set { ViewState["City"] = value; }
  } //实现属性Employee

  [ Bindable(true), Category("Appearance"), Description("员工信息"), DesignerSerializationVisibility( DesignerSerializationVisibility.Content), NotifyParentProperty(true) ]

  public Employee Employee {
   get {
    if (employee == null) {
     employee = new Employee();
    }
    return employee;
   }
  } // 重写RenderContents方法,自定义实现控件呈现

  protected override void RenderContents(HtmlTextWriter output) {
   output.Write("公司所在城市:");
   output.Write(City);
   output.WriteBreak();
   output.Write("姓名:");
   output.Write(Employee.Name.ToString());
   output.WriteBreak();
   output.Write("性别:");
   output.Write(Employee.Sex.ToString());
   output.WriteBreak();
   output.Write("职务:");
   output.Write(Employee.Title.ToString());
  }
 }
}

以上代码显示了自定义服务器控件Company的实现,其中主要包括了一些属性和RenderContents方法的内容。具体属性包括2个:一个是简单属性City,另一个是复杂属性Employee。简单属性City的实现使用了视图状态ViewState。复杂属性Employee则有些特别,其类型是一个类Employee。同时,该属性还设置了两个元数据属性:DesignerSerializationVisibility(DesignerSerializationVisibility.Content)和NotifyParentProperty(true)。前者可用于指定序列化程序应该序列化属性的内容即子属性,后者则可使得属性浏览器中对子属性的修改通知一直上传到对象模型,并在被修改了子属性的控件中产生修改通知。以上两个设计时元数据属性的设置是实现连字符形式复杂属性的关键之一。另一个关键之处在于为在实现复杂属性的子属性时未其设置元数据属性。

下面列举了具体实现复杂属性Employee的Employee.cs文件源代码。

以下为引用的内容:

using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Web.UI;
namespace WebControlLibrary{
 public class Employee {
  private string _name;
  private string _sex;
  private string _title; //实现构造函数1
  public Employee() { } //实现构造函数2
  public Employee(String Name, String Sex, String Title) {
   _name = Name; _sex = Sex; _title = Title;
  } //实现属性Name
  [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("员工姓名"), NotifyParentProperty(true) ]

  public String Name {
   get { return _name; }
   set { _name = value; }
  } //实现属性Sex

  [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("员工性别"), NotifyParentProperty(true) ]

  public String Sex {
   get { return _sex; }
   set { _sex = value; }
  } //实现属性Title

  [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("员工职务"), NotifyParentProperty(true) ]

  public String Title {
   get { return _title; }
   set { _title = value; }
  }
 }
}

以上代码实现了Employee类,其中包括构造函数和属性Name、Sex和Title。读者需要注意,为了实现连字符形式复杂属性,以上3个属性都必须设置元数据属性NotifyParentProperty(true)。这样,当子属性发生修改时,.NET框架将自动产生修改通知,并且通知到父属性Employee。

3、小结

本文通过一个典型示例介绍了创建连字符形式复杂属性的实现方法。对于其他形式的复杂属性,例如,内部嵌套形式复杂属性、内部嵌套形式默认复杂属性等,本文将不再做更多解释。实际上,实现复杂属性是有其自身规律可循的。只要读者能够按照规定的方法实现,基本上都不会出现太大的问题。