天天看點

一起談.NET技術,asp.net控件開發基礎(1)

  asp。net本身提供了很多控件,提供給我們這些比較懶惰的人使用,我認為控件的作用就在此,因為我們不想重複工作,是以要建立它,這個本身便是一個需求的關系,是以學習控件開發很有意思。 wrox網站上有本書 Professional ASP。NET 2.0 Server Control and Component Development,現在還沒有出版,但網站上放出了代碼,是以正好下載下傳過來學習一下。

  我看過前幾章代碼,環環相扣,作者用不同的知識向我們展示同一個效果,是以循序漸進的學下來很有好處。雖然自己對控件開發還不是很熟悉,但我感覺以下幾點很重要,是我自己總結的

1. 了解控件之間的繼承關系

  最好是先看看看System。Web。UI命名空間

  (1)Control 類,所有的控件都共享的一個類,你需要去看下其裡面受保護的幾個方法和屬性,雖然一下看不完,以後會發現常常用到這些方法,大家可以在MSDN看一下其派生類

  (2)HtmlTextWriter 類,不得不了解的一個類,主要工作就是我們寫的标記字元和文本輸出

2. 重寫方法

  (1) 必須繼承Control類

  (2) 重寫Control類的Render方法,這個是必須的,因為其他控件都繼承了Control 類類,是以幾乎所有控件都有這個方法

3. 熟悉中繼資料

  大家都知道asp。net控件屬性在編輯器上是分類的,如外觀,行為,布局等,每個屬性還給出了解釋。簡單的中繼資料就是起到這個作用,當然你也可以不加,但使用了中繼資料讓人感到有親切感,寫法如

  [CategoryAttribute("Appearance")]

  要使用中繼資料,必須引用System。ComponentModel命名控件,一般你如果寫元件的話,不可能不用到這樣類庫。具體的MSDN上有所介紹。

一. 輸出字元串

  說多了沒意思,還是來演練吧。首先你得了解HTML。來看下面代碼,效果就是輸出HTML到用戶端

  示例一

一起談.NET技術,asp.net控件開發基礎(1)

using System;

using System.Web.UI;

namespace CustomComponents

{

/// <summary>

/// Summary description for CreditCardForm

/// </summary>

public class CreditCardForm1 : Control

protected override void Render(HtmlTextWriter writer)

writer.Write("<table style='width:287px;height:124px;border-width:0;'>");

writer.Write("<tr>");

writer.Write("<td><strong>Payment Method</strong></td>");

writer.Write("<td>");

writer.Write("<select name='PaymentMethod' id='PaymentMethod' style='width:100%;'>");

writer.Write("<option value='0'>Visa</option>");

writer.Write("<option value='1'>MasterCard</option>");

writer.Write("</select>");

writer.Write("</td>");

writer.Write("</tr>");

writer.Write("<td><strong>Credit Card No.</strong></td>");

writer.Write("<td><input name='CreditCardNo' id='CreditCardNo' type='text' /></td>");

writer.Write("<td><strong>Cardholder's Name</strong></td>");

writer.Write("<td><input name='CardholderName' id='CardholderName' type='text' /></td>");

writer.Write("<td><strong>Expiration Date</strong></td>");

writer.Write("<select name='Month' id='Month'>");

for (int day = 1; day < 13; day++)

if (day < 10)

writer.Write("<option value='" + day.ToString() + "'>" + "0" + day.ToString() + "</option>");

else

writer.Write("<option value='" + day.ToString() + "'>" + day.ToString() + "</option>");

}

writer.Write("&nbsp");

writer.Write("<select name='Year' id='Year'>");

for (int year = 2005; year < 2015; year++)

writer.Write("<option value='" + year.ToString() + "'>" + year.ToString() + "</option>");

writer.Write("<td align='center' colspan='2'>");

writer.Write("<input type='submit' value='Submit' />");

writer.Write("</table>");

base.Render(writer);

  效果很簡單,其實就一直在輸出HTML再加幾個屬性,大家可以直接把代碼放在App_Code檔案夾裡,就可自動編譯,當然也可以建立web控件庫。注意要繼承Control類,重寫Render方法,用HtmlTextWriter類的Write輸出HTML

  使用控件

  (1). 需要先注冊一下

  <%@ Register TagPrefix="custom" Namespace="CustomComponents" %>

  (2) 然後就使用标簽輸出效果

  <custom:CreditCardForm1 runat="server" ID="ccf" />

  下為效果圖

一起談.NET技術,asp.net控件開發基礎(1)

二. 改善,加入屬性和中繼資料

  可能上面做出的 控件毫無用處,但卻可以讓你熟悉一下步驟,上面的控件定的很死,沒有定義任何屬性,用處不大,下面來改造我們來定義常用屬性,然後再輸出,這樣我們就可以修改控件的屬性了,

示例二

一起談.NET技術,asp.net控件開發基礎(1)

using System.ComponentModel;

[DefaultPropertyAttribute("CardholderNameText")]

[ToolboxData(@"<{0}:CreditCardForm2

PaymentMethodText='信用卡類型' CreditCardNoText='信用卡卡号'

CardholderNameText='信用卡持有者姓名' SubmitButtonText = '送出'

runat='server'></{0}:CreditCardForm2>")

]

public class CreditCardForm2 : Control

private string paymentMethodText = "信用卡類型";

private string creditCardNoText = "信用卡卡号";

private string cardholderNameText = "信用卡持有者姓名";

private string expirationDateText = "最後使用時間";

private string submitButtonText = "送出";

[BrowsableAttribute(true)]

[DescriptionAttribute("擷取和設定信用卡類型")]

[DefaultValueAttribute("信用卡類型")]

[CategoryAttribute("Appearance")]

public virtual string PaymentMethodText

get { return this.paymentMethodText; }

set { this.paymentMethodText = value; }

[DescriptionAttribute("擷取或設定信用卡卡号")]

[DefaultValueAttribute("信用卡卡号")]

public virtual string CreditCardNoText

get { return this.creditCardNoText; }

set { this.creditCardNoText = value; }

[DescriptionAttribute("擷取或設定信用卡持有者姓名")]

[DefaultValueAttribute("信用卡持有者姓名")]

public virtual string CardholderNameText

get { return this.cardholderNameText; }

set { this.cardholderNameText = value; }

[DescriptionAttribute("擷取或設定最後使用時間")]

[DefaultValueAttribute("最後使用時間")]

public virtual string ExpirationDateText

get { return this.expirationDateText; }

set { this.expirationDateText = value; }

[DescriptionAttribute("擷取或設定按鈕标簽")]

[DefaultValueAttribute("送出")]

public virtual string SubmitButtonText

get { return this.submitButtonText; }

set { this.submitButtonText = value; }

writer.Write("<td>" + PaymentMethodText + "</td>");

writer.Write("<td>" + CreditCardNoText + "</td>");

writer.Write("<td>" + CardholderNameText + "</td>");

writer.Write("<td>" + ExpirationDateText + "</td>");

writer.Write("<input type='submit' value='" + SubmitButtonText + "' />");

  上面我們接觸到了中繼資料了,意思應該很好了解,為了測試中繼資料的作用,大家可以建立一個類庫項目,然後把寫的代碼放這個項目裡面,接着web網站引用這個項目,成功生成以後,你會發現工具箱已經自動幫你加上了這幾個控件

一起談.NET技術,asp.net控件開發基礎(1)

 接着你要做的工作就是拖動你需要的控件,然後你會在屬性面闆看到下圖

一起談.NET技術,asp.net控件開發基礎(1)

  然後你再結合代碼中的中繼資料,應該就知道大概意思了。(可以根據你的了解結合MSDN看)

三. 再次改善,淘汰用Write方法以字元串的方式輸出HTML

  接着我們繼續發現問題,我們發現我們除了定義幾個需要自己來修改的屬性外,還是要用來大量的字元串用來輸出HTML,而且容易輸錯。是以HtmlTextWriter類提供幾個有用的方法用來代替。

  (1)AddStyleAttribute方法 為标簽添加樣式屬性

  (2)AddAttribute方法        為标簽添加屬性

  (3)RenderBeginTag          開始寫入标簽頭 如<table。。。。>

  (4)RenderEndTag            寫入标簽尾部,如</table>

  這裡有幾點需要特别注意。

  一. 因為其定義方式跟我們平時定義方式不同,我們平時寫HTML時,是先寫标簽開頭,再寫标簽的屬性。如<table borderwidth="0">,然而我們在使用上面幾個方法時,需要有先後順序,我們需要先定義标簽的屬性和樣式,然後再輸出标簽頭。

  二.标簽頭和尾,需一一對應。可以了解為嵌套關系。最好的了解方法就是輸出代碼後,檢視源檔案,再結合原來定義的代碼來看。還是看代碼比較容易說明,由于CreditCardForm2已經定義了我們需要的屬性,而我們現在要做的隻是用标簽的形式來替代字元串的形式,是以隻需要繼承CreditCardForm2類,重寫Render方法即可

  示例三

一起談.NET技術,asp.net控件開發基礎(1)

writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");

writer.RenderBeginTag(HtmlTextWriterTag.Table);

writer.RenderBeginTag(HtmlTextWriterTag.Tr);

writer.RenderBeginTag(HtmlTextWriterTag.Td);

writer.Write("<strong>" + PaymentMethodText + "</strong>");

writer.RenderEndTag();

writer.AddAttribute(HtmlTextWriterAttribute.Name, "PaymentMethod");

writer.AddAttribute(HtmlTextWriterAttribute.Id, "PaymentMethod");

writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");

writer.RenderBeginTag(HtmlTextWriterTag.Select);

writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");

writer.RenderBeginTag(HtmlTextWriterTag.Option);

writer.Write("Visa");

writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");

writer.Write("MasterCard");

writer.Write("<strong>" + CreditCardNoText + "</strong>");

writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");

writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");

writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");

writer.RenderBeginTag(HtmlTextWriterTag.Input);

writer.Write("<strong>" + CardholderNameText + "</strong>");

writer.AddAttribute(HtmlTextWriterAttribute.Name, "CardholderName");

writer.AddAttribute(HtmlTextWriterAttribute.Id, "CardholderName");

writer.Write("<strong>" + ExpirationDateText + "</strong>");

writer.AddAttribute(HtmlTextWriterAttribute.Name, "Month");

writer.AddAttribute(HtmlTextWriterAttribute.Id, "Month");

writer.AddAttribute(HtmlTextWriterAttribute.Value, day.ToString());

writer.Write("0" + day.ToString());

writer.Write(day);

writer.Write(" ");

writer.AddAttribute(HtmlTextWriterAttribute.Name, "Year");

writer.AddAttribute(HtmlTextWriterAttribute.Id, "Year");

writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());

writer.Write(year);

writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");

writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");

writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");

writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);

實作的效果雖然一樣,但上面的代碼是不是漂亮很多,而且不容易輸錯。這也是所提倡的做法

四. 未使用視圖狀态的後果

  還是視圖狀态,關于視圖狀态大家可以參考MSDN和相關文章, 看以下的示例,還是CreditCardForm3這個控件

一起談.NET技術,asp.net控件開發基礎(1)

if (!IsPostBack)

一起談.NET技術,asp.net控件開發基礎(1)
一起談.NET技術,asp.net控件開發基礎(1)
一起談.NET技術,asp.net控件開發基礎(1)
一起談.NET技術,asp.net控件開發基礎(1)

      creditcardform。CardholderNameText = "Full Name";

一起談.NET技術,asp.net控件開發基礎(1)

      creditcardform。CreditCardNoText = "CreditCardNo";

一起談.NET技術,asp.net控件開發基礎(1)

      creditcardform。ExpirationDateText = "ExpirationDate";

一起談.NET技術,asp.net控件開發基礎(1)

      creditcardform。PaymentMethodText = "Payment Options";

一起談.NET技術,asp.net控件開發基礎(1)

      creditcardform。SubmitButtonText = "Send";

一起談.NET技術,asp.net控件開發基礎(1)

    }

  首次加載效果

一起談.NET技術,asp.net控件開發基礎(1)

  點選按鈕以後

一起談.NET技術,asp.net控件開發基礎(1)

五。使用視圖狀态改善效果

  前提條件是你未禁用視圖狀态,繼承CreditCardForm3,改寫每個屬性

一起談.NET技術,asp.net控件開發基礎(1)

public override string PaymentMethodText

get { return ViewState["PaymentMethodText"] != null ? (string)ViewState["PaymentMethodText"] : "信用卡類型"; }

set { ViewState["PaymentMethodText"] = value; }

public override string CreditCardNoText

get { return ViewState["CreditCardNoText"] != null ? (string)ViewState["CreditCardNoText"] : "信用卡卡号"; }

set { ViewState["CreditCardNoText"] = value; }

public override string CardholderNameText

get { return ViewState["CardholderNameText"] != null ? (string)ViewState["CardholderNameText"] : "信用卡持有者姓名"; }

set { ViewState["CardholderNameText"] = value; }

public override string ExpirationDateText

get { return ViewState["ExpirationDateText"] != null ? (string)ViewState["ExpirationDateText"] : "最後使用時間"; }

set { ViewState["ExpirationDateText"] = value; }

public override string SubmitButtonText

get { return ViewState["SubmitButtonText"] != null ? (string)ViewState["SubmitButtonText"] : "送出"; }

set { ViewState["SubmitButtonText"] = value; }

  以上全為個人見解,如有錯誤,希望大家指出。

<a href="http://kb.cnblogs.com/page/75287/" target="_blank">下一篇:asp.net控件開發基礎(2)</a>

繼續閱讀