一、關於繼承方面
1. 繼承control類:
一般不可見html元素主要是繼承control類,比如meta中的元素或者隱藏域等
2.繼承webcontrol類:
一般可見元素比如<input type=text>等,爲了獲取更多的樣式支持,減少代碼量,一般直接繼承webcontrol:
比如分頁控件等:
http://blog.csdn.net/46539492/archive/2008/04/02/2244627.aspx
3.複合控件:
定義複合控件一般要繼承INamingContainer這個接口。比如一個簡單用戶登陸控件
http://blog.csdn.net/46539492/archive/2008/03/14/2182934.aspx
4.數據列表控件:
比如DropDownList,CheckBoxList等控件一般繼承ListControl,又因爲這些控件存在數據傳輸或者說數據回發,則要繼承IPostBackDataHandler接口。
5.複合列表控件
比如CheckBoxList,RadioButtonList等控件,除了繼承ListControl類,IPostBackDataHandler接口外,還要實現IRepeatInfoUser接口,IRepeatInfoUser接口定義了重複項列表的列表控件實現的屬性和方法,最後還因爲他們是複合控件,還要繼承INamingContainer接口6.數據綁定控件
(1)DataList
DataList類似於CheckBoxList,是重複項列表的列表控件,所以需要繼承IRepeatInfoUser,也是複合控件,所以繼承INamingContainer接口,此外還要繼承BaseDataList類,該類用數據列表控件的基類,如DataList和DataGrid,該類提供所有數據列表控件的所有方法和屬性。
(2)Repeater
Repeater比較靈活,繼承control和INamingContainer接口。
(3)DataGrid
DataGrid類,和DataList類似,主要繼承BaseDataList類和INamingContainer接口
(4)GridView
GridView是比較複雜的數據綁定控件,繼承CompositeDataBoundControl, IPostBackContainer, IPostBackEventHandler, ICallbackContainer, ICallbackEventHandler
其中CompositeDataBoundControl表示由其他服務器控件組成的表格數據綁定控件的基類; IPostBackContainer接口定義一個方法;使控件能夠獲取客戶端腳本選項。ICallbackContainer接口定義一個方法,使控件能夠獲取回調腳本;ICallbackEventHandler用於指示控件可以作爲服務器的回調事件的目標。
6.導航控件
(1)TreeView控件
TreeView控件主要繼承HierarchicalDataBoundControl, IPostBackEventHandler, IPostBackDataHandler, ICallbackEventHandler,其中HierarchicalDataBoundControl用作所有 ASP.NET 2.0 版數據綁定控件的基類,這些控件以分層形式顯示它們的數據。因爲有數據回發所以繼承IPostBackDataHandler,繼承IPostBackEventHandler處理回發事件,和GridView類似,ICallbackEventHandler用於指示控件可以作爲服務器的回調事件的目標
(2)Menu控件
Menu主要繼承HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer,因爲Menu是個複合控件,繼承INamingContainer接口。
二、樣式相關
1. 重寫TagKey
示例如下:
protected override HtmlTextWriterTag TagKey
...{
get
...{
return HtmlTextWriterTag.Table;
}
}
#endregion
默認是HtmlTextWriterTag.Span,當需要其它標籤時,需要重寫TagKey,
比如以下代碼:
<tr>
<td align="right">
當前第
<asp:Label ID="lblCurrentPage" runat="server"></asp:Label>頁,
總共<asp:Label ID="lblRecodeCount" runat="server"></asp:Label>條紀錄,
共<asp:Label ID="lblPageCount" runat="server"></asp:Label>頁,
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:LinkButton ID="lnkbtnFrist" runat="server" OnClick="lnkbtnFrist_Click"><font face=webdings color="red">9</font></asp:LinkButton>
<asp:LinkButton ID="lnkbtnPre" runat="server" OnClick="lnkbtnPre_Click"><font face=webdings color="red">7</font></asp:LinkButton>
<asp:LinkButton ID="lnkbtnNext" runat="server" OnClick="lnkbtnNext_Click"><font face=webdings color="red">8</font></asp:LinkButton>
<asp:LinkButton ID="lnkbtnLast" runat="server" OnClick="lnkbtnLast_Click"><font face=webdings color="red">:</font></asp:LinkButton>
跳轉到第<asp:TextBox ID="txtPageIndex" runat="server" style="width:40px;" onkeypress="myKeyDown();"></asp:TextBox>頁<asp:Button ID="BtnChangePage" runat="server" Text="GO" OnClick="BtnChangePage_Click" />
</td>
</tr>
</table>
這段代碼要寫成控件,就需要重寫TaGKey,改爲HtmlTextWriterTag.Table。
然後繪製控件:
protected override void RenderContents(HtmlTextWriter writer)
...{
if (ButtonStyle != null)
...{
_btnChangePage.ApplyStyle(ButtonStyle);
}
if (TextBoxStyle != null)
...{
_txtPageIndex.ApplyStyle(TextBoxStyle);
}
if (LabelStyle != null)
...{
_lblCurrentPage.ApplyStyle(LabelStyle);
_lblPageCount.ApplyStyle(LabelStyle);
_lblRecodeCount.ApplyStyle(LabelStyle);
_lblPageSize.ApplyStyle(LabelStyle);
}
AddAttributesToRender(writer);
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write("當前第");
if (_lblCurrentPage != null)
_lblCurrentPage.RenderControl(writer);
writer.Write("頁,每頁");
if (_lblPageSize != null)
...{
_lblPageSize.RenderControl(writer);
}
writer.Write("條紀錄,總共");
if (_lblRecodeCount != null)
_lblRecodeCount.RenderControl(writer);
writer.Write("條紀錄,共");
if (_lblPageCount != null)
_lblPageCount.RenderControl(writer);
writer.Write("頁 [ ");
if (_lnkbtnFrist != null)
...{
if (PageIndex == 1) //如果是第一頁,則第一頁灰顯,作用是避免不必要的點擊造成沒必要的數據傳輸
...{
_lnkbtnFrist.Enabled = false;
}
else
...{
_lnkbtnFrist.Enabled = true;
}
_lnkbtnFrist.RenderControl(writer);
}
writer.Write(" ");
if (_lnkbtnPre != null)
...{
if (PageIndex > 1) //如果當前頁大於1,則上一頁顯示,否則灰顯
...{
_lnkbtnPre.Enabled = true;
}
else
...{
_lnkbtnPre.Enabled = false;
}
_lnkbtnPre.RenderControl(writer);
}
writer.Write(" ");
if (_lnkbtnNext != null)
...{
if (_lblPageCount == null)
...{
_lnkbtnNext.Enabled = false;
}
else
...{
int pageCount = int.Parse(_lblPageCount.Text); //獲取總頁數
if (PageIndex < pageCount)//如果當前頁小於總頁數,則下一頁顯示,否則灰顯
...{
_lnkbtnNext.Enabled = true;
}
else
...{
_lnkbtnNext.Enabled = false;
}
}
_lnkbtnNext.RenderControl(writer);
}
writer.Write(" ");
if (_lnkbtnLast != null)
...{
if (_lblPageCount == null)
...{
_lnkbtnLast.Enabled = false;
}
else
...{
int pageCount = int.Parse(_lblPageCount.Text); //獲取總頁數
if (PageIndex == pageCount)//如果當前頁爲最後一頁,則末頁灰顯
...{
_lnkbtnLast.Enabled = false;
}
else
...{
_lnkbtnLast.Enabled = true;
}
}
_lnkbtnLast.RenderControl(writer);
}
writer.Write(" ]跳轉到第");
if (_txtPageIndex != null)
_txtPageIndex.RenderControl(writer);
writer.Write("頁");
if (_btnChangePage != null)
_btnChangePage.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
//base.RenderContents(writer);
}
#endregion
}
}
2.重寫CreateControlStyle
重寫CreateControlStyle,可以根據需要應用相關的樣式,比如繼承Label類,並重寫CreateControlStyle方法,使該控件具有表格的樣式:
...{
return new TableStyle(ViewState);
}
[BrowsableAttribute(true)]
[DescriptionAttribute("網格線")]
[CategoryAttribute("Appearance")]
public virtual GridLines GridLines
...{
get ...{ return ((TableStyle)ControlStyle).GridLines; }
set ...{ ((TableStyle)ControlStyle).GridLines = value; }
}
這樣該自定義的label就具有表格的樣式,比如網格線。
3.繼承webcontrol
通過繼承webcontrol類可以獲得webcontrol類很多樣式,比如:
4.通過繼承Style類來自定義Style
示例如下:
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace MyLabel
...{
public class LabelStyle:Style
...{
public LabelStyle() ...{ }
public LabelStyle(StateBag viewState) : base(viewState) ...{ }
public virtual String ImageUrl
...{
get ...{ return ViewState["imageUrl"] != null ? (string)ViewState["imageUrl"] : ""; }
set ...{ ViewState["imageUrl"] = value; }
}
//判斷視圖狀態是否爲空
internal bool IsSet(string key)
...{
return ViewState[key] != null;
}
/**//**/
/**//// <summary>
/// 是否定義樣式元素
/// </summary>
public override bool IsEmpty
...{
get
...{
return base.IsEmpty && !IsSet("imageUrl");
}
}
public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner)
...{
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, ImageUrl);
base.AddAttributesToRender(writer, owner);
}
}
}
使用方法:
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MyLabel
...{
public class MyLabel3:Label
...{
protected override Style CreateControlStyle()
...{
return new LabelStyle();//使用自定義的Style
}
[DefaultValue("")]
public virtual string ImageUrl
...{
get
...{
return ((LabelStyle)ControlStyle).ImageUrl;
}
set
...{
((LabelStyle)ControlStyle).ImageUrl = value;
}
}
}
}
三、屬性相關
1.簡單屬性
簡單屬性是指屬性值可以很容易轉換爲字符串表達式的屬性,這種屬性的值通常爲Boolean、Byte、Char、Double、Enum、Int32、DateTime等簡單數值類型,以及String類型和枚舉類型。開發人員可以通過添加代碼,將簡單屬性存儲在ViewState字典中,以在回發間進行狀態管理。
通常的示例如下:
[Category("Appearance")]
[Description("設置單擊當前行時當前行的背景色")]
public virtual Color ClickBackGroundColor
...{
get
...{
return ViewState["ClickBackGroundColor"]!=null?(Color)ViewState["ClickBackGroundColor"]:Color.Empty;
}
set
...{
ViewState["ClickBackGroundColor"] = value;
}
}
2.複雜屬性
如果一個屬性的類型是本身具有屬性(稱爲子屬性)的類,則該屬性就稱爲複雜屬性。例如,WebControl類的Font屬性的類型是本身具有屬性(如Bold和Name)的FontInfo類。Bold和Name是WebControl的Font屬性的子屬性。
複雜屬性不能簡單的用ViewState來進行狀態管理,需要自定義視圖狀態,比如我前一篇文章《千萬級數據分頁之二---一個簡單的自定義分頁控件》定義的ButtonStyle,TextBoxStyle等就屬於複雜屬性:
private Style _buttonStyle;
private Style _textBoxStyle;
private Style _linkButtonStyle;
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"應用於按鈕的樣式")
]
public virtual Style ButtonStyle
...{
get
...{
if (_buttonStyle == null)
...{
_buttonStyle = new Style();
if (IsTrackingViewState)
...{
((IStateManager)_buttonStyle).TrackViewState();
}
}
return _buttonStyle;
}
}
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"應用於鏈接按鈕的樣式")
]
public virtual Style LinkButtonStyle
...{
get
...{
if (_linkButtonStyle == null)
...{
_linkButtonStyle = new Style();
if (IsTrackingViewState)
...{
((IStateManager)_linkButtonStyle).TrackViewState();
}
}
return _linkButtonStyle;
}
}
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"應用於文本框的樣式")
]
public virtual Style TextBoxStyle
...{
get
...{
if (_textBoxStyle == null)
...{
_textBoxStyle = new Style();
if (IsTrackingViewState)
...{
((IStateManager)_textBoxStyle).TrackViewState();
}
}
return _textBoxStyle;
}
}
private Style _labelStyle;
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"應用於標籤的樣式")
]
public virtual Style LabelStyle
...{
get
...{
if (_labelStyle == null)
...{
_labelStyle = new Style();
if (IsTrackingViewState)
...{
((IStateManager)_labelStyle).TrackViewState();
}
}
return _labelStyle;
}
}
#endregion
自定義視圖狀態#region 自定義視圖狀態
protected override void LoadViewState(object savedState)
...{
if (savedState == null)
...{
base.LoadViewState(null);
return;
}
else
...{
Triplet t = savedState as Triplet;
if (t != null)
...{
base.LoadViewState(baseState);
if ((t.Second) != null)
...{
((IStateManager)ButtonStyle).LoadViewState(buttonStyleState);
}
if ((t.Third) != null)
...{
((IStateManager)TextBoxStyle).LoadViewState(textBoxStyleState);
}
if (labelStyleState != null)
...{
((IStateManager)(_labelStyle)).LoadViewState(labelStyleState);
}
if (linkButtonStyleState != null)
...{
((IStateManager)(_linkButtonStyle)).LoadViewState(linkButtonStyleState);
}
}
else
...{
throw new ArgumentException("Invalid view state .");
}
}
}
protected override object SaveViewState()
...{
baseState = base.SaveViewState();
buttonStyleState = null;
textBoxStyleState = null;
labelStyleState = null;
linkButtonStyleState = null;
if (_buttonStyle != null)
...{
buttonStyleState =
((IStateManager)_buttonStyle).SaveViewState();
}
if (_textBoxStyle != null)
...{
textBoxStyleState =
((IStateManager)_textBoxStyle).SaveViewState();
}
if (_labelStyle != null)
...{
labelStyleState = ((IStateManager)_labelStyle).SaveViewState();
}
if (_linkButtonStyle != null)
...{
linkButtonStyleState = ((IStateManager)_linkButtonStyle).SaveViewState();
}
return new Triplet(baseState,
buttonStyleState, textBoxStyleState);
}
protected override void TrackViewState()
...{
base.TrackViewState();
if (_buttonStyle != null)
...{
((IStateManager)_buttonStyle).TrackViewState();
}
if (_textBoxStyle != null)
...{
((IStateManager)_textBoxStyle).TrackViewState();
}
if (_labelStyle != null)
...{
((IStateManager)_labelStyle).TrackViewState();
}
if (_linkButtonStyle != null)
...{
((IStateManager)_linkButtonStyle).TrackViewState();
}
}
#endregion