您的位置:首页 > 编程语言 > ASP

ASP.Net开发者常见Datagrid错误

2008-09-13 22:22 411 查看
摘要:学习如何避免在使用ASP.NETDatagrid控件进行开发时可能发生的一些常见错误。
  Datagrid控件是Microsoft®ASP.NET中功能最强、用途最广的Web控件之一,这一点已经得到了ASP.NET权威人士的认同。虽然Datagrid控件易于使用,但同样易于给使用者带来麻烦。以下是许多人所犯的一些错误,这些人包括从初学者到富有经验的.NET专家。您可以看到许多苦闷的使用者在ASP.NET新闻组和论坛就这些错误提出问题。遵循本文概述的相当简单的步骤,可以帮助您避免这些错误,并节约大量的开发时间。
  
  可以使用Datagrid创建列表数据而没有使用
  我知道您不会再使用如下所示的代码,但ASP.NET领域中许多守旧的用户仍在继续使用它们:
  


 
  可以对以上代码进行简化,使其仅为:
  <asp:datagridrunat="server"datasource="MyDataReader"/>,并调用.DataBind()方法。即使需要对HTML输出进行特殊的控制,您也可以在用户界面上记录集的内容重复出现的情况下,使用某个数据Web控件。
  忘记在Page_Load事件中检查IsPostBack
  最常见的错误之一是忘记在数据绑定之前检查页面的IsPostBack条件。例如,Datagrid处于“Edit”(编辑)模式时,忽略该项检查将导致已编辑的值被数据源中的原始值覆盖。
  
  以下是包含IsPostBack检查的一个典型Page_Load事件。BindGrid()是一个例程,用于导入并设置Datagrid的数据源,并调用DataBind()方法。
  


 
  需要更大的灵活性时,仍坚持使用自动生成的列
  如果Datagrid所处的环境需要任何一种特殊格式,或是需要使用Datagrid中的其他任何Web控件,那么必须关闭AutoGenerateColumns。将AutoGenerateColumns属性的设置保持为“True”(默认设置)的做法,仅在最简单的Datagrid方案中有效。但对几乎所有实际的应用程序,必须将该属性设置为“False”,并在Datagrid声明的<columns></columns>段中明确地指定列。MicrosoftVisualStudio®.NET用户可以使用属性生成器以图形化的方式创建这些列。
  
  注意:如果将AutoGenerateColumns的设置保持为“True”,并且在Datagrid的<columns>段中指定了列,那么最终将得到对列的重复设置。系统将首先显示特别声明的列,随后是所有自动生成的列。
  
  尝试仅使用控件ID来引用Datagrid项目中的控件
  许多人没有认识到,对于Datagrid的TemplateColumn下的ItemTemplate中的控件(例如带有“MyTextBox”ID的TextBox控件),不能在后面的代码或是在ASPX页面的<script>段中用如下所示的代码来直接调用该控件:
  
 


  该代码将导致可怕的“名称‘MyTextBox’没有声明”错误。
  
  因为Datagrid是由多个行(项目)组成的,所以数据源中的每一行实际都会有一个单独的“MyTextBox”实例。ASP.NET在每个控件的ID前面加上该控件层次结构中每个命名容器的ID,这样Textbox将具有唯一的ID,与页面中所有其他控件的ID都不相同。例如,如果MyTextBox处于DataGrid1中,那么生成的ID将是DataGrid1:_ctl2:MyTextBox。“_ctl2”代表MyTextBox所处的当前行。页面中其他MyTextBox实例的ID可能是DataGrid1:_ctl3:MyTextBox、DataGrid1:_ctl4:MyTextBox等等。要检索需要查找的“MyTextBox”值,需要对适当的DataGridItem调用FindControl方法。该DataGridItem用作TextBox的父命名容器。
  HTML
  


 
  代码
  


 
  对FindControl调用的结果调用CType,将会把返回值由Object类型强制转换成TextBox类型,以访问.Text属性。
  
  可以(或应该)使用分页而没有使用
  用户未必希望在单个页面上滚动查看成千上万条记录。请确保您的应用程序设计合理,能够处理可能会返回大量记录的情况。
  
  忘记在每个Datagrid事件中执行.DataBind()调用,从而导致回发
  一个常见的问题是:“当我点击Datagrid某一行中的Edit(编辑)链接时,页面回发,且不包含任何数据。这是什么错误?”问题在于数据仅在页面第一次被调用时绑定到网格。在每个Datagrid事件(Edit、Update、Cancel、Page或Sort)中,请确保设置了Datagrid的Datasource属性(除非已经在<asp:Datagrid>声明中通过声明的方式进行了设置),并对Datagrid调用了DataBind()方法。
  
  运行时不必要地在Datagrid中动态创建Datagrid控件或列
  在某些业务和技术方案中,在运行时创建ASP.NET控件是必要的,也是完全合适的。例如,有时需要在选择其他页面选项后,才能在运行时确定用户界面。或是要创建一个复合服务器控件,其中的每个子控件都需要动态创建,因为无法以声明的方式创建这些子控件。如果遇到这些情况,请注意,提交页面时不要保留这些动态控件。必须在页面生命周期的早期,在每次回发时重新创建动态控件(例如在Page_Init事件中)。警言:创建控件要早,创建控件要勤。
  
  然而,如果Datagrid应用程序中不是一定需要动态创建控件,请避免使用该技术,以免遇到麻烦。尽管可能创建动态Datagrid,但它们会引发各种事件,这通常都会令人头疼。换句话说,不要动态创建控件,以避免因为创建控件使ASPX文件变得散乱。
  
  持续使用大型ViewState
  Datagrid控件会在页面中添加大量的ViewState,这一点令人讨厌,因为这会导致呈现给用户的页面的总体大小急剧增加。要使页面大小不增加,最简单的方法是无论对整个页面,还是单独对某些特定的控件,都禁用ViewState。例如,如果页面不产生回发,那么对整个页面禁用ViewState是安全的。否则,请对两次回发之间状态信息不会发生更改的各个控件禁用ViewState,或者对不需要隐藏字段来跟踪自身状态的那些控件禁用ViewState。
  
  对Datagrid控件或包含Datagrid的页面禁用ViewState时,如果Datagrid会启动回发事件,那么需要执行一些特殊的步骤。首先,必须在每次回发时在Page_Load中重新绑定Datagrid。这有违常规做法(以及上述第二个问题中的描述)。但如果禁用ViewState,该步骤是必需的,这样在执行Page_Load后可以正确地引发其他Datagrid事件。如果要处理以下Datagrid事件中的任何一部分(或全部),那么还需要在ViewState中手动存储一些Datagrid属性。例如,在禁用了ViewState的Datagrid中进行编辑时,只要是在Page_Load中第一次绑定Datagrid之前重新存储EditItemIndex,且Datagrid处于编辑模式,那么只需将EditItemIndex储存到ViewState就够了(请参阅示例代码)。
  表1:Datagrid事件与ViewState的依赖关系
  


 
  清单1:启用编辑、排序和分页,但禁用ViewState的Datagrid的示例代码。
  


 
使用ItemDataBound或ItemCreated事件时,忘记检查适当的ListItemType
  Datagrid控件对每个数据行引发两个事件。首次将每行添加到Datagrid时将引发ItemCreated事件,将数据绑定到每行时将引发ItemDataBound事件。添加单元格到Datagrid的表格输出时,这些事件可以用于控制每个单元格的外观或内容。例如,可以基于数值的范围修改单元格的背景颜色。但关键是要记住,这些事件的引发针对的是所有Datagrid项目类型,包括页眉、页脚和分页程序项目。如果执行ItemDataBound事件期间,没有在引用项目的数据之前仔细检查项目类型,第一个项目(通常是标题行)就将发生错误。如果Datagrid启用了分页,且将其设置为在顶端显示,那么第一个项目就会成为分页程序项目。以下示例代码显示如何在引用项目数据之前进行正确的ListItemType检查。不要忘了AlternatingItem!  



需要对生成的HTML有更多的控制时,过多地使用了Datagrid(Repeater也许是更好的选择)

如果懒散的程序员喜欢Datagrid控件(因为Datagrid控件为他们完成了很多工作),那么有着极强控制欲的程序员必定喜欢Repeater控件。如果需要或希望完全控制创建的所有HTML,请使用Repeater控件,它能帮助您完成该任务。Repeater控件在性能上也略占优势,因为它不像Datagrid控件的所有内置功能那样占用系统资源。也可以考虑使用折衷的DataList控件,它具备编辑和排序功能,同时还具有在一行内重复显示记录的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: