笑望人生

微笑面对人生,开心享受生活。
数据加载中……

Asp.Net中DataGrid的模版列(TemplateColumn)内容控制简单方法。

最近写了几个asp.net的项目。其中,Asp.Net的控件DataGrid使用的最多了,前几天需要一个功能,我研究了很长时间,发现一个方法,应该是最简单的实现。现表述如下。

DataGrid的html定义很简单,如下
<Asp:DataGrid ID="myDatagrid" runat="server" datakeyfield="fID" AutoGenerateColumns="False">
  
<Columns>
    
<Asp:TemplateColumn itemstyle-width=".." ..>
        
<ItemTemplate>
            .
        
</ItemTemplate>
    
</Asp:TemplateColumn>
  
</Columns>
</Asp:DataGrid>

功能的要求是在 ItemTemplate中,有可能是一个绑定数据源的:
<a href="...">...</a>
链接代码,也有可能是一个
<span>...</span>
显示文本代码,而判断的根据是绑定到DataGrid中数据源的DataTable中每行的某一特定列的内容。

说白了,功能就是DataGrid在绑定数据生成行的时候,判断数据源DataTable每行DataRow中一个字段的内容,这个字段类型是bool类型,如果为true,则这个列显示的是<a href="...">...</a>链接,而如果是false,则显示<span>...</span>文本。而显示的链接内指向的地址必须执行数据绑定。就是这个DataGrid的列有的行要数据绑定,有的行不要数据绑定。

功能需求分析到这里,那么现在该思考如何实现了。

我当时了解需求后,马上反应出来,使用DataGrid自带的BoundColumn、HyperLinkColumn肯定是不行的。而且,使用TemplateColumn也有麻烦。他只能放一些固定的控件,如html控件或服务器控件等。后来我没有办法了,准备继承ITemplate接口自己开发一个模版列。后来又觉得麻烦。因为绑定的时候需要一个类似于BoundColumn功能的绑定数据源内容的东西。后来我发现了这个方法。

在查看.Net Framework SDK 文档的时候,我发现在<Asp:TemplateColumn>中的<ItemTemplate>中可以放类似于
<%# DataBinder.Eval(Container.DataItem, "fID"%>
这样的数据绑定代码,我就想是否可以再加入代码呢

我做了一个试验,试验结果发现上面的代码(包括前面和后面的<% %>符号)输出的实际上是一个object对象,然后DataGrid显示的时候把它转换成字符串。后来我就想,是否可以前面再加入代码,调用这个页面的后台代码中的方法。

我们都知道,在asp.net1.1中,一个名称为aaa.aspx的asp.net页在asp.net内部处理时是一个名叫ASP.aaa_aspx的类,这个类继承它的后台代码aaa.aspx.cs中的类,这个类继承System.Web.UI.Page类,从而实现需要的功能。这就是说,在asp.net 1.1中,我们在.aspx中的以<% %> 包含的代码可以调用后台cs类中的以public 和protected生命的任何方法。

这就好办了,既然从上面的数据绑定代码可以获取主键内容(是个字符串),那么我可以在后台写一个方法,这个方法有一个字符串参数,返回的也是字符串。这个返回的字符串就是显示在列中的内容。

首先说一下绑定表的内容,如下
列名 类型 用途
fID System.String 表主键
hasSub System.Boolean 判断的依据
contentUrl System.String 链接的地址

然后是后台代码中C#代码
protected string GetDGColumn(string id)
{
    
// 从数据源获取DataTable内容略
    DataTable dt = .;
    
// 定义DataTable的主键列
    DataColumn[] key = {dt.Columns["fID"]};
    dt.PrimaryKey 
= key;

    
// 根据传入的id开始找数据行
    DataRow row = dt.Rows.Find(id);

    
// 找到后开始判断
    if((bool)row["hasSub"])
    
{
        
// hasSub为 true,表示返回<span>
        return "<span style=\"\">内容内容</span>";
    }

    
else
    
{
        
// hasSub列为false,返回链接
        return "<a href=\"XXXX.aspx?id="+id+"\" target=\"_blank\">链接内容</a>";
    }

}

然后在.aspx中的DaaGrid内这样定义:
<Asp:DataGrid ID="myDatagrid" runat="server" datakeyfield="fID" AutoGenerateColumns="False"> 
  
<Columns> 
    
<Asp:TemplateColumn itemstyle-width=".." ..> 
        
<ItemTemplate> 
            
<%# base.GetDGColumn((object)DataBinder.Eval(Container.DataItem, "fID")) %>
        
</ItemTemplate> 
    
</Asp:TemplateColumn> 
  
</Columns> 
</Asp:DataGrid>

利用了DataGrid绑定时内部使用的数据绑定方法获取结果,然后把结果传递给GetDGColumn()方法,DataGrid列的内容实际上是使用的这个方法返回的字符串。


好了,一个随心所欲生成DataGrid列内容的方法说完了,不知道大家有没有更好的方法。
我这个方法的缺点就是生成的内容没有办法执行服务器提交,它无法被服务器段区分开,所以只能是使用静态的链接,文本等。还有就是可以调用客户端的js脚本。如果谁有更好的方法,如生成的链接按钮的单击事件可以被服务器端区分,请指教。如果大家有更好的方法,也请指教。我在这里谢谢大家了。

posted on 2004-12-16 14:09 笑望人生 阅读(5814) 评论(14)  编辑 收藏 所属分类: 写程序的心得和感想。

评论

#1楼    回复  引用    

可以使用datagrid的item_databind事件吧,在事件里做判断,然后生成相应的控件。
2004-12-16 15:26 | kly [未注册用户]

#2楼    回复  引用  查看    

这个事件我用过,太麻烦了,它传递的事件数据不全,一个Item,根据它找列,还要生成控件,加内容,太麻烦了。
2004-12-16 16:38 | 笑望人生      

#3楼    回复  引用    

要想让生成的控件能够被服务器端识别,,必须在生成它后注册到页面的controls里面,同时指定ranat=server,这样模板列里面的控件就可以和一般的web控件一样啦
2004-12-16 23:10 | cc [未注册用户]

#4楼    回复  引用  查看    

这种方法不好,UI的构造写在了代码中,一旦ui需要变化,比如样式,那么还需要重新编译。
我的方法是这样的:模版列中添加两个服务器控件,一个是链接,一个是Label,他们的Visible属性邦定到那个控制字段即可。
2005-01-14 10:09 | eng21      

#5楼    回复  引用    

同意eng21的观点。
2005-01-29 13:42 | Rbmxxx [未注册用户]

#6楼    回复  引用    

请问一下:
用datagrid控件,怎么得到字段的一部分

如字段xxx的值为123456,我只要123

急,谢谢
2005-04-27 15:24 | cfq [未注册用户]

#7楼    回复  引用    

怎么在datagrid的模板列的button按钮上实现对话框,就是说按下button会弹出一个对话框
2005-06-01 22:54 | fyb [未注册用户]

#8楼    回复  引用    

在datagrid的模板列中添加了一个按钮,我怎么可以在后台编写代码处理这个button触发的事件呢?(我现在不知道如何捕捉该事件,既不知道该事件的类型)
2005-07-05 16:55 | xyq [未注册用户]

#9楼    回复  引用    

在datagrid的模板列中添加了一个按钮,我怎么可以在后台编写代码处理这个button触发的事件呢?(我现在不知道如何捕捉该事件,既不知道该事件的类型)
2005-08-19 10:32 | flying [未注册用户]

#10楼    回复  引用    

模板列允许您任意和静态文本,以此为基础为列创建自定义布局。
哈哈,我看Library时,就看到了上面这句话,然后我就用类似你上面的方法来做了,像你所说的,这种方法确实没法响应服务器,如果要实现这个功能的话,要用控件混合.呵呵,我没有像你那天严重,研究了好几天,看样子我比较幸运~~~~~~~~~
2005-08-23 09:31 | breaker [未注册用户]

#11楼    回复  引用    

为什么在DataGrid的模板列中添加链接并传递参数而这个参数不是DataGrid中的字段值
2005-09-06 14:33 | 冰凌 [未注册用户]

#12楼    回复  引用    

响应 DataList、Repeater 或 DataGrid 项中的按钮事件请参见
介绍 DataList Web 服务器控件 | 介绍 Repeater Web 服务器控件 | 介绍 DataGrid Web 服务器控件 | 允许用户删除 DataList Web 服务器控件中的项 | 允许用户编辑 DataList Web 服务器控件中的项 | 允许用户选择 DataList Web 服务器控件中的项 | 在 Web 窗体页中创建事件处理程序
如果 DataList、Repeater 或 DataGrid 控件模板包括 Button、LinkButton 或 ImageButton Web 服务器控件,则这些按钮可将它们的单击事件积极发送到容器控件 DataList、Repeater 或 DataGrid 中。这使您得以拥有实现尚未为 DataList 和 DataGrid 控件定义的功能(编辑、删除、更新和取消)的按钮,而且允许为 Repeater 控件定义功能。

响应 DataList、Repeater 和 DataGrid 控件中的按钮事件

在控件模板中包括 Button、LinkButton 或 ImageButton。将按钮的 CommandName 属性设置为标识其功能的字符串,如“排序”或“复制”。
创建用于控件的 ItemCommand 事件的方法。在该方法中,执行下列操作:
检查事件参数对象的 CommandSource 属性的 CommandName 属性,查看传递的是什么字符串。
为用户单击的按钮执行相应的逻辑。
注意 如果您调用了父控件(DataList、Repeater 或 DataGrid 控件)的 DataBind 方法,ItemCommand 事件将不会发生,原因是父控件的内容已经重置。因此,您通常不需要在每次往返时调用 DataBind 方法(即在初始化页时无需检查发回)。有关详细信息,请参阅数据绑定多记录 Web 服务器控件和在设计时数据绑定单值 Web 服务器控件。
下面的示例显示可如何响应 DataList 控件中的按钮单击。在该示例中,ItemTemplate 包含显示购物车的 ImageButton 控件。该按钮发送命令 AddToCart。ItemCommand 事件处理程序确定单击了哪个按钮,而且如果是购物车按钮的话,则执行相应的逻辑。

' Visual Basic
Private Sub DataList1_ItemCommand(ByVal source As Object, _
ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _
Handles DataList1.ItemCommand
If (e.CommandName = "AddToCart") Then
' Add code here to add the item to the shopping cart.
' Use the value of e.Item.ItemIndex to find the data row
' in the data source.
End If
End Sub

// C#
private void DataList1_ItemCommand(object source,
System.Web.UI.WebControls.DataListCommandEventArgs e)
{
if (e.CommandName == "AddToCart")
{
// Add code here to add the item to the shopping cart.
// Use the value of e.Item.ItemIndex to find the data row
// in the data source.
}
}
有关使用 DataList Web 服务器控件的示例,请参阅允许用户选择 DataList Web 服务器控件中的项。

2006-06-28 14:51 | 浏览器 [未注册用户]

#13楼    回复  引用    

顶,您说的太对了。
2006-10-14 11:32 | ouyang [未注册用户]

#14楼    回复  引用    

这种方法的确不错。不过2003好象不支持啊。
2007-07-13 14:11 | 老七 [未注册用户]

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-12-16 14:13 编辑过