DataControlField与Parameter扩展
2007-06-05 15:39 Clingingboy 阅读(3816) 评论(3) 编辑 收藏 举报
示例代码请参考此篇
一.为数据绑定控件(GridView)自定义列(DataControlField)
本来asp.net1.1中已经存在DataGrid了,其中为我们提供了丰富的数据字段类型(即不同绑定列),如下代码
<asp:DataGrid ID="dg1" runat="server">
<Columns>
<asp:BoundColumn></asp:BoundColumn>
<asp:ButtonColumn></asp:ButtonColumn>
<asp:HyperLinkColumn></asp:HyperLinkColumn>
<asp:TemplateColumn></asp:TemplateColumn>
</Columns>
</asp:DataGrid>
网上也有介绍扩展DataGridColumn类的方法,asp.net2.0新增的GridView定义了全新的数据列,其也可以用于DetailsView,即DataControlField类
来看下其内置列的实现

DataControlField类为数据列的基类,其派生类相信大家都很熟悉,如下图

当然我们这里讨论的不是怎么使用这些列,而是如何实现自定义列的过程.实现方法跟以前的有些相似,还是抽象类DataControlField为我们实现了一些常用方法,并定义了一些必须让我们去实现的方法,让字类去重写.
下面列出常用相关的方法
这里以自定义CalendarField列为例
看DataControlField的CloneField()方法,先创建对象,再复制属性
protected internal DataControlField CloneField()
{
DataControlField newField = this.CreateField();
this.CopyProperties(newField);
return newField;
}
1.创建列对象
DataControlField提供了CopyProperties 方法,此工作一定要做
protected override DataControlField CreateField()
{
return new CalendarField();
}
2.复制属性
DataControlField提供了CopyProperties 方法
首先要先定义你需要的属性,然后将属性复制给CloneField方法中创建的对象,在更改属性时要记得调用OnFieldChanged方法,通知DataControlField对象状态发生变化,触发FieldChanged事件
3.初始化单元格状态(InitializeCell方法)
即把你自己定义的东西添加到表格中。这里需要注意顺序
我们知道GridView的单元格(即DataControlCellType)分为三种类型,页眉,页脚,数据项,到了确定是数据项以后,又要给数据行分类型
如编辑,插入,交替,选中等(即DataControlRowState)
如BoundField在普通状态下是文本,在编辑状态下是TextBox.这里就是要做这个工作,在不同状态下,加载不同控件。如下代码
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{

base.InitializeCell(cell, cellType, rowState, rowIndex);

//如果为数据项
if (cellType == DataControlCellType.DataCell)
InitializeDataCell(cell, rowState);
}

protected virtual void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
Control ctrl = null;

DataControlRowState state = rowState & DataControlRowState.Edit;

//根据状态加载不同控件
if ((!ReadOnly && (state != DataControlRowState.Normal)) || rowState == DataControlRowState.Insert)
{
Calendar cal = new Calendar();
cal.ToolTip = this.HeaderText;
cell.Controls.Add(cal);

if ((DataField.Length != 0) &&
(DataField.Length != 0))
ctrl = cal;

_inInsertMode = rowState == DataControlRowState.Insert;
}
else if (DataField.Length != 0)
{
ctrl = cell;
}

//给控件赋绑定的值
if ((ctrl != null) && Visible)
{
ctrl.DataBinding += new EventHandler(this.OnBindingField);
}
}
4.实现数据交互(ExtractValuesFromCell方法)
第三步骤是显示信息,这里则需要提取字段的值,然后添加到dictionary集合中.具体其他操作暂且不管。
public override void ExtractValuesFromCell(IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
{
object selectedValue = null;
if (cell.Controls.Count > 0)
{
Calendar cal = cell.Controls[0] as Calendar;

if (cal == null)
{
throw new InvalidOperationException("CalendarField could not extract control.");
}
else
selectedValue = cal.SelectedDate;
}

// Add the value to the dictionary
if (dictionary.Contains(DataField))
dictionary[DataField] = selectedValue;
else
dictionary.Add(DataField, selectedValue);
}
5.给列添加设计时支持
BoundField列在有字段绑定的情况下,在设计时显示如下

其是通过GetDesignTimeValue方法实现的,如可以这样定义
protected virtual string GetDesignTimeValue()
{
return "<select><option>Databound Date</option></select>";
}
在页面效果如下
好了,大致步骤就如此,你只需要熟悉上面方法,照着步骤做一遍就可以了.
另外还有DataGrid的DataGridColumn,如果你理解上面DataControlField的做法的话,DataGridColumn的实现关键方法则是InitializeCell,方法比较相似.但其没有ExtractValuesFromCell方法,因为DataGrid当时还没有这么的智能化的自动编辑功能.
二.数据源控件控件自定义参数
数据源控件我们也比较常用,所以要学习下如何自定义参数,如下图,为内置已经实现的几个参数类.

我们还是关注下Parameter类,其主要提供了一个空的Evaluate 方法给,派生类需要实现此方法返回经过更新的值.其实现比较简单,来看下其内部QueryStringParameter的实现过程.应该说没什么难度.抓住重点就好
public class QueryStringParameter : Parameter
{
public QueryStringParameter()
{
}

protected QueryStringParameter(QueryStringParameter original) : base(original)
{
this.QueryStringField = original.QueryStringField;
}

public QueryStringParameter(string name, string queryStringField) : base(name)
{
this.QueryStringField = queryStringField;
}

public QueryStringParameter(string name, TypeCode type, string queryStringField) : base(name, type)
{
this.QueryStringField = queryStringField;
}

protected override Parameter Clone()
{
return new QueryStringParameter(this);
}

protected override object Evaluate(HttpContext context, Control control)
{
if ((context != null) && (context.Request != null))
{
return context.Request.QueryString[this.QueryStringField];
}
return null;
}

public string QueryStringField
{
get
{
object obj2 = base.ViewState["QueryStringField"];
if (obj2 == null)
{
return string.Empty;
}
return (string) obj2;
}
set
{
if (this.QueryStringField != value)
{
base.ViewState["QueryStringField"] = value;
base.OnParameterChanged();
}
}
}
}
三.属性集合
以上的DataControlField和Parameter都具有集合类型DataControlFieldCollection和ParameterCollection
有时候扩展了以后可能还需要更改集合类型,因为有时候集合类型是在开发人员在功能已经实现的情况下编写的.现在的扩展势必需要发生一些改变.而属性类型一更改,控件内部的集合属性也需要更改.当然偷懒的话就不改了,这么一改比较麻烦.但这种事情还是会碰到的.这里就提一下.
好了就这么写一下,希望对大家有帮助.本人已经在上海的某家公司工作.
今后的工作大多会更多地设计到控件的开发上,希望与大家多交流
一.为数据绑定控件(GridView)自定义列(DataControlField)
本来asp.net1.1中已经存在DataGrid了,其中为我们提供了丰富的数据字段类型(即不同绑定列),如下代码








来看下其内置列的实现

DataControlField类为数据列的基类,其派生类相信大家都很熟悉,如下图

当然我们这里讨论的不是怎么使用这些列,而是如何实现自定义列的过程.实现方法跟以前的有些相似,还是抽象类DataControlField为我们实现了一些常用方法,并定义了一些必须让我们去实现的方法,让字类去重写.
下面列出常用相关的方法
这里以自定义CalendarField列为例
看DataControlField的CloneField()方法,先创建对象,再复制属性







1.创建列对象
DataControlField提供了CopyProperties 方法,此工作一定要做




2.复制属性
DataControlField提供了CopyProperties 方法
首先要先定义你需要的属性,然后将属性复制给CloneField方法中创建的对象,在更改属性时要记得调用OnFieldChanged方法,通知DataControlField对象状态发生变化,触发FieldChanged事件

3.初始化单元格状态(InitializeCell方法)
即把你自己定义的东西添加到表格中。这里需要注意顺序
我们知道GridView的单元格(即DataControlCellType)分为三种类型,页眉,页脚,数据项,到了确定是数据项以后,又要给数据行分类型
如编辑,插入,交替,选中等(即DataControlRowState)
如BoundField在普通状态下是文本,在编辑状态下是TextBox.这里就是要做这个工作,在不同状态下,加载不同控件。如下代码








































4.实现数据交互(ExtractValuesFromCell方法)
第三步骤是显示信息,这里则需要提取字段的值,然后添加到dictionary集合中.具体其他操作暂且不管。





















5.给列添加设计时支持
BoundField列在有字段绑定的情况下,在设计时显示如下

其是通过GetDesignTimeValue方法实现的,如可以这样定义




在页面效果如下

好了,大致步骤就如此,你只需要熟悉上面方法,照着步骤做一遍就可以了.
另外还有DataGrid的DataGridColumn,如果你理解上面DataControlField的做法的话,DataGridColumn的实现关键方法则是InitializeCell,方法比较相似.但其没有ExtractValuesFromCell方法,因为DataGrid当时还没有这么的智能化的自动编辑功能.
二.数据源控件控件自定义参数
数据源控件我们也比较常用,所以要学习下如何自定义参数,如下图,为内置已经实现的几个参数类.

我们还是关注下Parameter类,其主要提供了一个空的Evaluate 方法给,派生类需要实现此方法返回经过更新的值.其实现比较简单,来看下其内部QueryStringParameter的实现过程.应该说没什么难度.抓住重点就好

























































三.属性集合
以上的DataControlField和Parameter都具有集合类型DataControlFieldCollection和ParameterCollection
有时候扩展了以后可能还需要更改集合类型,因为有时候集合类型是在开发人员在功能已经实现的情况下编写的.现在的扩展势必需要发生一些改变.而属性类型一更改,控件内部的集合属性也需要更改.当然偷懒的话就不改了,这么一改比较麻烦.但这种事情还是会碰到的.这里就提一下.
好了就这么写一下,希望对大家有帮助.本人已经在上海的某家公司工作.
今后的工作大多会更多地设计到控件的开发上,希望与大家多交流
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现