掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
本篇將開始介紹如自定義ASP.NET數(shù)據(jù)綁定控件,這里感謝很多人的支持,有你們的支持很高興.

成都創(chuàng)新互聯(lián)公司憑借專業(yè)的設(shè)計(jì)團(tuán)隊(duì)扎實(shí)的技術(shù)支持、優(yōu)質(zhì)高效的服務(wù)意識(shí)和豐厚的資源優(yōu)勢(shì),提供專業(yè)的網(wǎng)站策劃、成都做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)站優(yōu)化、軟件開發(fā)、網(wǎng)站改版等服務(wù),在成都十載的網(wǎng)站建設(shè)設(shè)計(jì)經(jīng)驗(yàn),為成都成百上千中小型企業(yè)策劃設(shè)計(jì)了網(wǎng)站。
這里首先需要大家熟悉ASP.NET模板控件的使用,還有自定義模板控件.因?yàn)閿?shù)據(jù)綁定控件多是基于模板控件的.
ASP.NET數(shù)據(jù)綁定控件一.回顧
如果你使用過ASP.NET內(nèi)置的數(shù)據(jù)控件(如DataList,Repeater),你一定會(huì)這么做
1.設(shè)置數(shù)據(jù)源 DataSource屬性
2.調(diào)用數(shù)據(jù)綁定 DataBind方法
3.在控件的不同模板內(nèi)使用綁定語法顯示數(shù)據(jù)
這三步應(yīng)該是必須要做的
其他更多的
你可能需要對(duì)綁定的數(shù)據(jù)進(jìn)行統(tǒng)一的一些操作(如時(shí)間格式化),或者對(duì)數(shù)據(jù)的某一項(xiàng)進(jìn)行操作(對(duì)某一項(xiàng)進(jìn)行格式化),或者需要觸發(fā)模板控件內(nèi)的一些事件(如databound事件).
根據(jù)上面的一些需求,我們需要這樣做
1.對(duì)綁定的數(shù)據(jù)進(jìn)行統(tǒng)一的一些操作: 為數(shù)據(jù)綁定控件定義Item項(xiàng)(表示列表的一條數(shù)據(jù), 如Repeater的RepeaterItem)
2.對(duì)數(shù)據(jù)的某一項(xiàng)進(jìn)行操作: 因?yàn)槎x了Item項(xiàng),那你肯定需要一個(gè)ItemCollection集合,其可以方便的為你檢索數(shù)據(jù)
3.因?yàn)槎x了RepeaterItem,原先的EventArgs和CommandEventArgs已經(jīng)無法滿足需求,我們需要自定義委托及其一個(gè)為控件提供數(shù)據(jù)的的ItemEventArgs
上面三點(diǎn)有些并非必須定義,如第2點(diǎn),還需要根據(jù)具體需求來定.但一個(gè)完成的控件是需要的.
ASP.NET數(shù)據(jù)綁定控件二.為數(shù)據(jù)控件做好準(zhǔn)備
這次的demo為不完整的Datalist控件,來源還是MSDN的例子,我們命名為TemplatedList,此控件未定義ItemCollection集合
好了,根據(jù)上面的分析我們先為TemplatedList提供項(xiàng)和委托及為事件提供數(shù)據(jù)的幾個(gè)EventArgs,請(qǐng)看下面類圖
1.TemplatedListCommandEventArgs為Command事件提供數(shù)據(jù)
2.TemplatedListItemEventArgs為一般項(xiàng)提供數(shù)據(jù)
3.TemplatedListItem表示TemplatedList的項(xiàng)
ASP.NET數(shù)據(jù)綁定控件三.編寫TemplatedList
1.TemplatedList主要功能簡(jiǎn)介
提供一個(gè)ItemTemplate模板屬性,提供三種不同項(xiàng)樣式,ItemCommand 事件冒泡事件及4個(gè)事件
2.實(shí)現(xiàn)主要步驟
以下為必須
(1)控件必須實(shí)現(xiàn) System.Web.UI.INamingContainer 接口
(2)定義至少一個(gè)模板屬性
(3)定義DataSource數(shù)據(jù)源屬性
(4)定義控件項(xiàng)DataItem,即模板的一個(gè)容器
(5)重寫DataBind 方法及復(fù)合控件相關(guān)方法(模板控件為特殊的復(fù)合控件)
當(dāng)然還有其他額外的屬性,樣式,事件
3.具體實(shí)現(xiàn)
下面我們來具體看實(shí)現(xiàn)方法
(1)定義控件成員屬性
- #region 靜態(tài)變量
- private static readonly object EventSelectedIndexChanged = new object();
- private static readonly object EventItemCreated = new object();
- private static readonly object EventItemDataBound = new object();
- private static readonly object EventItemCommand = new object();
- #endregion
- 成員變量#region 成員變量
- private IEnumerable dataSource;
- private TableItemStyle itemStyle;
- private TableItemStyle alternatingItemStyle;
- private TableItemStyle selectedItemStyle;
- private ITemplate itemTemplate;
- #endregion
- 控件屬性#region 控件屬性
- [
- Category("Style"),
- Description("交替項(xiàng)樣式"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- NotifyParentProperty(true),
- PersistenceMode(PersistenceMode.InnerProperty),
- ]
- public virtual TableItemStyle AlternatingItemStyle
- {
- get
- {
- if (alternatingItemStyle == null)
- {
- alternatingItemStyle = new TableItemStyle();
- if (IsTrackingViewState)
- ((IStateManager)alternatingItemStyle).TrackViewState();
- }
- return alternatingItemStyle;
- }
- }
- [
- Category("Style"),
- Description("一般項(xiàng)樣式"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- NotifyParentProperty(true),
- PersistenceMode(PersistenceMode.InnerProperty),
- ]
- public virtual TableItemStyle ItemStyle
- {
- get
- {
- if (itemStyle == null)
- {
- itemStyle = new TableItemStyle();
- if (IsTrackingViewState)
- ((IStateManager)itemStyle).TrackViewState();
- }
- return itemStyle;
- }
- }
- [
- Category("Style"),
- Description("選中項(xiàng)樣式"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- NotifyParentProperty(true),
- PersistenceMode(PersistenceMode.InnerProperty),
- ]
- public virtual TableItemStyle SelectedItemStyle
- {
- get
- {
- if (selectedItemStyle == null)
- {
- selectedItemStyle = new TableItemStyle();
- if (IsTrackingViewState)
- ((IStateManager)selectedItemStyle).TrackViewState();
- }
- return selectedItemStyle;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(-1),
- Description("The cell padding of the rendered table.")
- ]
- public virtual int CellPadding
- {
- get
- {
- if (ControlStyleCreated == false)
- {
- return -1;
- }
- return ((TableStyle)ControlStyle).CellPadding;
- }
- set
- {
- ((TableStyle)ControlStyle).CellPadding = value;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(0),
- Description("The cell spacing of the rendered table.")
- ]
- public virtual int CellSpacing
- {
- get
- {
- if (ControlStyleCreated == false)
- {
- return 0;
- }
- return ((TableStyle)ControlStyle).CellSpacing;
- }
- set
- {
- ((TableStyle)ControlStyle).CellSpacing = value;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(GridLines.None),
- Description("The grid lines to be shown in the rendered table.")
- ]
- public virtual GridLines GridLines
- {
- get
- {
- if (ControlStyleCreated == false)
- {
- return GridLines.None;
- }
- return ((TableStyle)ControlStyle).GridLines;
- }
- set
- {
- ((TableStyle)ControlStyle).GridLines = value;
- }
- }
- [
- Bindable(true),
- Category("Data"),
- DefaultValue(null),
- Description("數(shù)據(jù)源"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
- ]
- public IEnumerable DataSource
- {
- get
- {
- return dataSource;
- }
- set
- {
- dataSource = value;
- }
- }
- [
- Browsable(false),
- DefaultValue(null),
- Description("項(xiàng)模板"),
- PersistenceMode(PersistenceMode.InnerProperty),
- TemplateContainer(typeof(TemplatedListItem))
- ]
- public virtual ITemplate ItemTemplate
- {
- get
- {
- return itemTemplate;
- }
- set
- {
- itemTemplate = value;
- }
- }
- [
- Bindable(true),
- DefaultValue(-1),
- Description("選中項(xiàng)索引,默認(rèn)為-1")
- ]
- public virtual int SelectedIndex
- {
- get
- {
- object o = ViewState["SelectedIndex"];
- if (o != null)
- return (int)o;
- return -1;
- }
- set
- {
- if (value < -1)
- {
- throw new ArgumentOutOfRangeException();
- }
- //獲取上次選中項(xiàng)
- int oldSelectedIndex = SelectedIndex;
- ViewState["SelectedIndex"] = value;
- if (HasControls())
- {
- Table table = (Table)Controls[0];
- TemplatedListItem item;
- //第一次選中項(xiàng)不執(zhí)行
- if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
- {
- item = (TemplatedListItem)table.Rows[oldSelectedIndex];
- //判斷項(xiàng)類型,為了將選中項(xiàng)還原為數(shù)據(jù)項(xiàng)
- if (item.ItemType != ListItemType.EditItem)
- {
- ListItemType itemType = ListItemType.Item;
- if (oldSelectedIndex % 2 != 0)
- itemType = ListItemType.AlternatingItem;
- item.SetItemType(itemType);
- }
- }
- //第一次執(zhí)行此項(xiàng),并一直執(zhí)行
- if ((value != -1) && (table.Rows.Count > value))
- {
- item = (TemplatedListItem)table.Rows[value];
- item.SetItemType(ListItemType.SelectedItem);
- }
- }
- }
- }
- #endregion
成員如下(可以看上面類圖)
1.三個(gè)項(xiàng)樣式和三個(gè)樣式屬性
2.公開DataSource數(shù)據(jù)源屬性,一個(gè)模板屬性
3.SelectedIndex索引屬性
前面的相信大家都很容易明白,其中的三個(gè)項(xiàng)樣式我們需要為其重寫視圖狀態(tài)管理,不熟悉可以看以前的隨筆,這里不再重復(fù).
SelectedIndex屬性比較復(fù)雜,這里重點(diǎn)介紹此屬性
SelectedIndex索引屬性默認(rèn)為-1,
我給出了注釋,在賦值前先記錄下了上次的選中項(xiàng),為恢復(fù)樣式而做準(zhǔn)備
- //獲取上次選中項(xiàng)
- int oldSelectedIndex = SelectedIndex;
- ViewState["SelectedIndex"] = value;
當(dāng)?shù)谝淮胃腟electedIndex屬性時(shí)只執(zhí)行下列代碼(將此項(xiàng)標(biāo)記為選中項(xiàng)),因?yàn)槌跏蓟瘯r(shí)的沒有oldSelectedIndex,不需要恢復(fù)樣式
- //第一次執(zhí)行此項(xiàng),并一直執(zhí)行
- if ((value != -1) && (table.Rows.Count > value))
- {
- item = (TemplatedListItem)table.Rows[value];
- item.SetItemType(ListItemType.SelectedItem);
- }
再次執(zhí)行時(shí),恢復(fù)oldSelectedIndex選中項(xiàng)樣式
- //第一次選中項(xiàng)不執(zhí)行
- if ((oldSelectedIndex != -1) && (table.Rows.Count > oldSelectedIndex))
- {
- item = (TemplatedListItem)table.Rows[oldSelectedIndex];
- //判斷項(xiàng)類型,為了將選中項(xiàng)還原為數(shù)據(jù)項(xiàng)
- if (item.ItemType != ListItemType.EditItem)
- {
- ListItemType itemType = ListItemType.Item;
- if (oldSelectedIndex % 2 != 0)
- itemType = ListItemType.AlternatingItem;
- item.SetItemType(itemType);
- }
- }
相信這樣的解釋你會(huì)明白
(2)定義控件成員事件
我們可以用上剛才我們聲明的委托了,即然你定義了這么多事件,就該為其安排觸發(fā)的先后.所以這個(gè)要特別注意,等下會(huì)再次提到.
- #region 事件
- protected virtual void OnItemCommand(TemplatedListCommandEventArgs e)
- {
- TemplatedListCommandEventHandler onItemCommandHandler = (TemplatedListCommandEventHandler)Events[EventItemCommand];
- if (onItemCommandHandler != null) onItemCommandHandler(this, e);
- }
- protected virtual void OnItemCreated(TemplatedListItemEventArgs e)
- {
- TemplatedListItemEventHandler onItemCreatedHandler = (TemplatedListItemEventHandler)Events[EventItemCreated];
- if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
- }
- protected virtual void OnItemDataBound(TemplatedListItemEventArgs e)
- {
- TemplatedListItemEventHandler onItemDataBoundHandler = (TemplatedListItemEventHandler)Events[EventItemDataBound];
- if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
- }
- protected virtual void OnSelectedIndexChanged(EventArgs e)
- {
- EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
- if (handler != null) handler(this, e);
- }
- [
- Category("Action"),
- Description("Raised when a CommandEvent occurs within an item.")
- ]
- public event TemplatedListCommandEventHandler ItemCommand
- {
- add
- {
- Events.AddHandler(EventItemCommand, value);
- }
- remove
- {
- Events.RemoveHandler(EventItemCommand, value);
- }
- }
- [
- Category("Behavior"),
- Description("Raised when an item is created and is ready for customization.")
- ]
- public event TemplatedListItemEventHandler ItemCreated
- {
- add
- {
- Events.AddHandler(EventItemCreated, value);
- }
- remove
- {
- Events.RemoveHandler(EventItemCreated, value);
- }
- }
- [
- Category("Behavior"),
- Description("Raised when an item is data-bound.")
- ]
- public event TemplatedListItemEventHandler ItemDataBound
- {
- add
- {
- Events.AddHandler(EventItemDataBound, value);
- }
- remove
- {
- Events.RemoveHandler(EventItemDataBound, value);
- }
- }
- [
- Category("Action"),
- Description("Raised when the SelectedIndex property has changed.")
- ]
- public event EventHandler SelectedIndexChanged
- {
- add
- {
- Events.AddHandler(EventSelectedIndexChanged, value);
- }
- remove
- {
- Events.RemoveHandler(EventSelectedIndexChanged, value);
- }
- }
- #endregion
(3)關(guān)鍵實(shí)現(xiàn)
我們?yōu)榭丶峁┝诉@么多東西,剩下的事情就是要真正去實(shí)現(xiàn)功能了
1.重寫DataBind方法
當(dāng)控件綁定數(shù)據(jù)時(shí)首先會(huì)執(zhí)行此方法觸發(fā)DataBinding事件
- //控件執(zhí)行綁定時(shí)執(zhí)行
- public override void DataBind()
- {
- base.OnDataBinding(EventArgs.Empty);
- //移除控件
- Controls.Clear();
- //清除視圖狀態(tài)信息
- ClearChildViewState();
- //創(chuàng)建一個(gè)帶或不帶指定數(shù)據(jù)源的控件層次結(jié)構(gòu)
- CreateControlHierarchy(true);
- ChildControlsCreated = true;
- TrackViewState();
- }
2.CreateControlHierarchy方法
- /**////
- /// 創(chuàng)建一個(gè)帶或不帶指定數(shù)據(jù)源的控件層次結(jié)構(gòu)
- ///
- /// 指示是否要使用指定的數(shù)據(jù)源
- //注意:當(dāng)?shù)诙螆?zhí)行數(shù)據(jù)綁定時(shí),會(huì)執(zhí)行兩遍
- private void CreateControlHierarchy(bool useDataSource)
- {
- IEnumerable dataSource = null;
- int count = -1;
- if (useDataSource == false)
- {
- // ViewState must have a non-null value for ItemCount because this is checked
- // by CreateChildControls.
- count = (int)ViewState["ItemCount"];
- if (count != -1)
- {
- dataSource = new DummyDataSource(count);
- }
- }
- else
- {
- dataSource = this.dataSource;
- }
- //根據(jù)項(xiàng)類型開始創(chuàng)建子控件
- if (dataSource != null)
- {
- Table table = new Table();
- Controls.Add(table);
- //選中項(xiàng)索引
- int selectedItemIndex = SelectedIndex;
- //項(xiàng)索引
- int index = 0;
- //項(xiàng)數(shù)量
- count = 0;
- foreach (object dataItem in dataSource)
- {
- ListItemType itemType = ListItemType.Item;
- if (index == selectedItemIndex)
- {
- itemType = ListItemType.SelectedItem;
- }
- else if (index % 2 != 0)
- {
- itemType = ListItemType.AlternatingItem;
- }
- //根據(jù)不同項(xiàng)索引創(chuàng)建樣式
- CreateItem(table, index, itemType, useDataSource, dataItem);
- count++;
- index++;
- }
- }
- //執(zhí)行綁定時(shí)執(zhí)行時(shí)執(zhí)行
- if (useDataSource)
- {
- //保存項(xiàng)數(shù)量
- ViewState["ItemCount"] = ((dataSource != null) ? count : -1);
- }
- }
- //創(chuàng)建項(xiàng)
- private TemplatedListItem CreateItem(Table table,
網(wǎng)站名稱:ASP.NET數(shù)據(jù)綁定控件開發(fā)淺析
本文鏈接:http://uogjgqi.cn/article/dhseijh.html

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流