Clingingboy

<developer name=’'clingingboy">
<i:Interaction.Behaviors>
<clingingboy:madeControlBehavior />
</i:Interaction.Behaviors>
</developer>

博客园 首页 新随笔 联系 订阅 管理
  211 Posts :: 1 Stories :: 1440 Comments :: 484 Trackbacks
        首先请下载示例代码
        
本篇将开始介绍如自定义数据绑定控件,这里感谢很多人的支持,有你们的支持很高兴.

这里首先需要大家熟悉asp.net模板控件的使用,还有自定义模板控件.因为数据绑定控件多是基于模板控件的.


一.回顾

如果你使用过asp.net内置的数据控件(如DataList,Repeater),你一定会这么做


1.设置数据源 DataSource属性
2.调用数据绑定  DataBind方法
3.在控件的不同模板内使用绑定语法显示数据

这三步应该是必须要做的

其他更多的

你可能需要对绑定的数据进行统一的一些操作(如时间格式化),或者对数据的某一项进行操作(对某一项进行格式化),或者需要触发模板控件内的一些事件(如databound事件).

根据上面的一些需求,我们需要这样做

1.对绑定的数据进行统一的一些操作: 为数据绑定控件定义Item项(表示列表的一条数据, 如Repeater的RepeaterItem)

2.对数据的某一项进行操作:
因为定义了Item项,那你肯定需要一个ItemCollection集合,其可以方便的为你检索数据

3.因为定义了RepeaterItem,原先的EventArgs和CommandEventArgs已经无法满足需求,我们需要自定义委托及其一个为控件提供数据的的ItemEventArgs

上面三点有些并非必须定义,如第2点,还需要根据具体需求来定.但一个完成的控件是需要的.


二.为数据控件做好准备

这次的demo为不完整的Datalist控件,来源还是MSDN的例子,我们命名为TemplatedList,此控件未定义ItemCollection集合

好了,根据上面的分析我们先为TemplatedList提供项和委托及为事件提供数据的几个EventArgs,请看下面类图





1.TemplatedListCommandEventArgs为Command事件提供数据

2.TemplatedListItemEventArgs为一般项提供数据

3.TemplatedListItem表示TemplatedList的项

三.编写TemplatedList

1.TemplatedList主要功能简介

提供一个ItemTemplate模板属性,提供三种不同项样式,ItemCommand 事件冒泡事件及4个事件





2.实现主要步骤

以下为必须

(1)控件必须实现 System.Web.UI.INamingContainer 接口

(2)定义至少一个模板属性

(3)定义DataSource数据源属性

(4)定义控件项DataItem,即模板的一个容器

(5)重写DataBind 方法及复合控件相关方法(模板控件为特殊的复合控件)

当然还有其他额外的属性,样式,事件


3.具体实现



下面我们来具体看实现方法

(1)定义控件成员属性



成员如下(可以看上面类图)

1.三个项样式和三个样式属性

2.公开DataSource数据源属性,一个模板属性

3.SelectedIndex索引属性

前面的相信大家都很容易明白,其中的三个项样式我们需要为其重写视图状态管理,不熟悉可以看以前的随笔,这里不再重复.

SelectedIndex属性比较复杂,这里重点介绍此属性

SelectedIndex索引属性默认为-1,

我给出了注释,在赋值前先记录下了上次的选中项,为恢复样式而做准备

                //获取上次选中项
                int oldSelectedIndex = SelectedIndex;
                ViewState[
"SelectedIndex"= value;


当第一次更改SelectedIndex属性时只执行下列代码(将此项标记为选中项),因为初始化时的没有oldSelectedIndex,不需要恢复样式

//第一次执行此项,并一直执行
                    if ((value != -1&& (table.Rows.Count > value))
                    
{
                        item 
= (TemplatedListItem)table.Rows[value];
                        item.SetItemType(ListItemType.SelectedItem);
                    }

再次执行时,恢复oldSelectedIndex选中项样式
                    //第一次选中项不执行
                    if ((oldSelectedIndex != -1&& (table.Rows.Count > oldSelectedIndex))
                    
{
                        item 
= (TemplatedListItem)table.Rows[oldSelectedIndex];
                        
//判断项类型,为了将选中项还原为数据项
                        if (item.ItemType != ListItemType.EditItem)
                        
{
                            ListItemType itemType 
= ListItemType.Item;
                            
if (oldSelectedIndex % 2 != 0)
                                itemType 
= ListItemType.AlternatingItem;
                            item.SetItemType(itemType);
                        }

                    }

相信这样的解释你会明白

(2)定义控件成员事件

我们可以用上刚才我们声明的委托了,即然你定义了这么多事件,就该为其安排触发的先后.所以这个要特别注意,等下会再次提到.



(3)关键实现

我们为控件提供了这么多东西,剩下的事情就是要真正去实现功能了

1.重写DataBind方法

当控件绑定数据时首先会执行此方法触发DataBinding事件

        //控件执行绑定时执行
        public override void DataBind()
        
{

            
base.OnDataBinding(EventArgs.Empty);

            
//移除控件
            Controls.Clear();
            
//清除视图状态信息
            ClearChildViewState();

            
//创建一个带或不带指定数据源的控件层次结构
            CreateControlHierarchy(true);
            ChildControlsCreated 
= true;

            TrackViewState();
        }


2.CreateControlHierarchy方法


CreateItem方法辅助用于创建项模板,此处注意事件触发顺序,上面已经提到过

此方法根据项索引创建控件中不同的Item项 ,ViewState["ItemCount"]表示项的数量,第一次触发时或者重新执行DataBind方法时方法参数为true,并在初始化以后(回发期间)CreateChildControls方法会调用此方法,其参数为false

数据源不再是实际的数据源,而是新定义的DummyDataSource,其主要实现了一个迭代



原因很明显,为了减少对数据源的访问,所以我们平时操作数据的时候,必须重新执行DataBind方法,原因就在此

好了,到了这里差不多主要的事情我们已经完成.接着把剩下的也完成

3.呈现

又到了Render方法这里了

此方法体只要执行了PrepareControlHierarchy方法,不同的方法做不同的事情,CreateControlHierarchy方法根据索引值指定了不同的项,PrepareControlHierarchy则为不同项呈现不同的样式效果



终于差不多了,经过这么多步骤,我们终于完成了,让我们来使用控件,看一下效果



又完成一个并不完美的控件,本来还该继续下去的,怕篇幅太大,到这里还没结束,只是刚开始,下次我们继续
posted on 2007-02-10 21:50 Clingingboy 阅读(5963) 评论(21)  编辑 收藏 网摘 所属分类: B Asp.net组件开发A Asp.net技术

Feedback

大侠又来了
  回复  引用    

#2楼 2007-02-10 22:44 webabcd      
终于又有动作了,等你等得好辛苦

  回复  引用  查看    

#3楼[楼主] 2007-02-10 22:50 Clingingboy      
@虫虫
@webabcd
谢谢各位的关注, 我会尽快继续写下去,webabcd的GridView扩展很好用

  回复  引用  查看    

#4楼 2007-02-10 23:25 teana      
高手终于现身了。。。你的文章通俗易懂。。。非常棒。。
  回复  引用  查看    

#5楼 2007-02-10 23:45 Cat Chen      
如果通过DataSourceID设置DataSource控件呢?
  回复  引用  查看    

#6楼[楼主] 2007-02-11 00:01 Clingingboy      
@Cat Chen
这个以后我会继续,DataSourceID和DataSource两个属性的设置只能2选一

不可越步学习-_-

  回复  引用  查看    

#7楼 2007-02-11 10:15 Cat Chen      
@Clingingboy
这个我知道,但是到了ASP.NET 2.0,我觉得就应该用DataSourceID,因为自动化程度更高,避免手工DataBind带来的差错。

  回复  引用  查看    

#8楼 2007-02-11 12:57 天才書生      
呵呵,很好的教程,向您多多学习了
  回复  引用  查看    

#9楼 2007-02-11 13:29 PE[未注册用户]
我发了封邮件给你,请查收.
clinging_boy - yahoo - com - cn

  回复  引用    

#10楼[楼主] 2007-02-11 13:52 Clingingboy      
@PE
收到,感谢你的邀请-_-

  回复  引用  查看    

#11楼 2007-02-12 20:33 JesseZhao      
@Cat Chen
请参考我最近写的文章,truelove项目感悟3,里面有详细介绍

  回复  引用  查看    

#12楼[楼主] 2007-02-12 20:51 Clingingboy      
@JesseZhao
谢谢,又提供了很好的学习资源

  回复  引用  查看    

#13楼 2007-02-14 21:25 Riancy[未注册用户]
以前的代码怎么不可以下了?
  回复  引用    

#14楼[楼主] 2007-02-14 22:58 Clingingboy      
哪里?
  回复  引用  查看    

谢谢,帮助很大!
  回复  引用    

#16楼 2007-03-31 08:25 ererer[未注册用户]
我支持 !

  回复  引用    

#17楼 2008-01-31 10:36 simcxcx[未注册用户]
楼主,你好,怎么我把你的代码考过去运行,老是显示:Unkown server tag 'custom:at'
  回复  引用    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 647062 YZQ1oDFtZaY=



相关文章:

相关链接: