知识大全 常见Datagrid错误

Posted

篇首语:只有努力攀登顶峰的人,才能把顶峰踩在脚下。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 常见Datagrid错误相关的知识,希望对你有一定的参考价值。

常见Datagrid错误  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  摘要 学习如何避免在使用 ASP NET Datagrid 控件进行开发时可能发生的一些常见错误(本文包含一些指向英文站点的链接)

目录

  可以使用 Datagrid 创建列表数据而没有使用 忘记在 Page_Load 事件中检查 IsPostBack需要更大的灵活性时 仍坚持使用自动生成的列 尝试仅使用控件 ID 来引用 Datagrid 项目中的控件 可以(或应该)使用分页而没有使用忘记在每个 Datagrid 事件中执行 DataBind() 调用 从而导致回发 运行时不必要地在 Datagrid 中动态创建 Datagrid 控件或列 持续使用大型 ViewState 使用 ItemDataBound 或 ItemCreated 事件时 忘记检查适当的 ListItemType 需要对生成的 HTML 有更多的控制时 过多地使用了 Datagrid(Repeater 也许是更好的选择) 参考资料

  datagrid 控件是 Microsoft® ASP NET 中功能最强 用途最广的 Web 控件之一 这一点已经得到了 ASP NET 权威人士的认同 虽然 Datagrid 控件易于使用 但同样易于给使用者带来麻烦 以下是许多人所犯的一些错误 这些人包括从初学者到富有经验的 NET 专家 您可以看到许多苦闷的使用者在 ASP NET 新闻组和论坛就这些错误提出问题 遵循本文概述的相当简单的步骤 可以帮助您避免这些错误 并节约大量的开发时间

可以使用 Datagrid 创建列表数据而没有使用

  我知道您不会再使用如下所示的代码 但 ASP NET 领域中许多守旧的用户仍在继续使用它们

  Response Write( <table> ) While MyDataReader Read() Response Write( <tr> ) Response Write( <td> ) Response Write(MyDataReader( )) Response Write( </td> ) Response Write( </tr> ) Loop Response Write( </table> )

  可以对以上代码进行简化 使其仅为

  <asp:datagrid runat= server datasource= MyDataReader /> 并调用 databind() 方法 即使需要对 HTML 输出进行特殊的控制 您也可以在用户界面上记录集的内容重复出现的情况下 使用某个数据 Web 控件

忘记在 Page_Load 事件中检查 IsPostBack

  最常见的错误之一是忘记在数据绑定之前检查页面的 IsPostBack 条件 例如 Datagrid 处于 Edit (编辑)模式时 忽略该项检查将导致已编辑的值被数据源中的原始值覆蓋 然而 该规则至少有一个主要的例外 请参阅持续使用大型 ViewState

  以下是包含 IsPostBack 检查的一个典型 Page_Load 事件 BindGrid() 是一个例程 用于导入并设置 Datagrid 的数据源 并调用 databind() 方法

  Sub Page_Load If Not IsPostBack Then BindGrid() End If End Sub

需要更大的灵活性时 仍坚持使用自动生成的列

  如果 Datagrid 所处的环境需要任何一种特殊格式 或是需要使用 Datagrid 中的其他任何 Web 控件 那么必须关闭 autogeneratecolumns 将 autogeneratecolumns 属性的设置保持为 True (默认设置)的做法 仅在最简单的 Datagrid 方案中有效 但对几乎所有实际的应用程序 必须将该属性设置为 False 并在 Datagrid 声明的 <columns></columns> 段中明确地指定列 Microsoft Visual Studio® NET 用户可以使用属性生成器以图形化的方式创建这些列

注意 如果将 AutoGenerateColumns 的设置保持为 True 并且在 Datagrid 的 <columns> 段中指定了列 那么最终将得到对列的重复设置 系统将首先显示特别声明的列 随后是所有自动生成的列
尝试仅使用控件 ID 来引用 Datagrid 项目中的控件

  许多人没有认识到 对于 Datagrid 的 TemplateColumn 下的 ItemTemplate 中的控件(例如带有 MyTextBox ID 的 TextBox 控件) 不能在后面的代码或是在 ASPX 页面的 <script> 段中用如下所示的代码来直接调用该控件

  Dim MyValue As String = MyTextBox Text

  该代码将导致可怕的 名称 MyTextBox 没有声明 错误

  因为 Datagrid 是由多个行(项目)组成的 所以数据源中的每一行实际都会有一个单独的 MyTextBox 实例 ASP NET 在每个控件的 ID 前面加上该控件层次结构中每个命名容器的 ID 这样 Textbox 将具有唯一的 ID 与页面中所有其他控件的 ID 都不相同 例如 如果 MyTextBox 处于 DataGrid 中 那么生成的 ID 将是 DataGrid :_ctl :MyTextBox _ctl 代表 MyTextBox 所处的当前行 页面中其他 MyTextBox 实例的 ID 可能是 DataGrid :_ctl :MyTextBox DataGrid :_ctl :MyTextBox 等等 要检索需要查找的 MyTextBox 值 需要对适当的 DataGridItem 调用 findcontrol 方法 该 DataGridItem 用作 TextBox 的父命名容器

  

  <asp:Datagrid runat= server id= Datagrid > <Columns> <asp:TemplateColumn> <ItemTemplate> <asp:TextBox runat= server id= MyTextBox /> </ItemTemplate> </asp:TemplateColumn> </Columns>

  代码

  Sub DataGrid _UpdateCommand(sender As Object _ e As DataGridCommandEventArgs) Dim MyValue As String = _ CType(e Item FindControl( MyTextBox ) TextBox) Text 对 MyValue 执行操作 End Sub

  对 FindControl 调用的结果调用 CType 将会把返回值由 Object 类型强制转换成 TextBox 类型 以访问 Text 属性

可以(或应该)使用分页而没有使用

  用户未必希望在单个页面上滚动查看成千上万条记录 请确保您的应用程序设计合理 能够处理可能会返回大量记录的情况 有关如何在 Datagrid 中实现分页的信息 请参阅 Paging in DataGrid QuickStart Tutorial 在 Scott Mitchell 的文章 Creating a Pageable Sortable DataGrid 中可以找到更多的信息

忘记在每个 Datagrid 事件中执行 DataBind() 调用 从而导致回发

  一个常见的问题是 当我点击 Datagrid 某一行中的 Edit(编辑)链接时 页面回发 且不包含任何数据 这是什么错误? 问题在于数据仅在页面第一次被调用时绑定到网格 在每个 Datagrid 事件(edit update cancel page 或 sort)中 请确保设置了 Datagrid 的 datasource 属性(除非已经在 <asp:Datagrid> 声明中通过声明的方式进行了设置) 并对 Datagrid 调用了 databind() 方法

运行时不必要地在 Datagrid 中动态创建 Datagrid 控件或列

  在某些业务和技术方案中 在运行时创建 ASP NET 控件是必要的 也是完全合适的 例如 有时需要在选择其他页面选项后 才能在运行时确定用户界面 或是要创建一个复合服务器控件 其中的每个子控件都需要动态创建 因为无法以声明的方式创建这些子控件 如果遇到这些情况 请注意 提交页面时不要保留这些动态控件 必须在页面生命周期的早期 在每次回发时重新创建动态控件(例如在 page_init 事件中) 警言 创建控件要早 创建控件要勤 有关如何动态创建控件的详细信息 请参阅 Microsoft Knowledge Base 文章 HOW TO:Dynamically Create Controls in ASP NET with Visual Basic NET

  然而 如果 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 就够了(请参阅示例代码)

  表 Datagrid 事件与 ViewState 的依赖关系

事件 是否依赖于 ViewState? 要存储在 ViewState 中的字段 itemcreated   无 itemdatabound   无 sortmand 是 SortExpression editmand 是 EditItemIndex pageindexchanged 是 CurrentPageIndex selectedindexchanged   无

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

  Sub Page_Load If Not ViewState( EditItemIndex ) Is Nothing Then Datagrid EditItemIndex = ViewState( EditItemIndex ) End If If Not ViewState( CurrentPageIndex ) Is Nothing Then Datagrid CurrentPageIndex = ViewState( CurrentPageIndex ) End If BindGrid() End Sub Sub BindGrid() Dim DV As DataView DV = GetDataSource() DV Sort = ViewState( SortExpression ) Datagrid DataSource = DV Datagrid DataBind() End Sub Sub Datagrid _SortCommand(s As Object _ e As DataGridSortCommandEventArgs) ViewState( SortExpression ) = e SortExpression BindGrid() End Sub Sub Datagrid _EditCommand(s As Object _ e As DatagridCommandEventArgs) Datagrid EditItemIndex = e Item ItemIndex ViewState( EditItemIndex ) = e Item ItemIndex BindGrid() End Sub Sub Datagrid _PageIndexChanged(s as Object _ e As DataGridPageChangedEventArgs) Datagrid CurrentPageIndex = e NewPageIndex ViewState( CurrentPageIndex ) = e NewPageIndex BindGrid() End Sub

使用 ItemDataBound 或 ItemCreated 事件时 忘记检查适当的 ListItemType

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

  Sub DataGrid _ItemDataBound(source As Object _ e As DataGridItemEventArgs) If (e Item ItemType = ListItemType Item Or _ e Item ItemType = ListItemType AlternatingItem) Then If e Item DataItem( ForumDate ) < DateTime Today Then e Item Cells( ) BackColor = System Drawing Color FromName( #ffccff ) End If End If End Sub

需要对生成的 HTML 有更多的控制时 过多地使用了 Datagrid(Repeater 也许是更好的选择) cha138/Article/program/net/201311/13697

相关参考

知识大全 DataGrid中的按钮反选事件

DataGrid中的按钮反选事件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  DataGrid

知识大全 DataGrid的ViewState

DataGrid的ViewState  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  减少View

知识大全 DataGrid脚眉显示合计

DataGrid脚眉显示合计  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  创建一个全局变量  

知识大全 用DataGrid浏览数据相关实例

用DataGrid浏览数据相关实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  数据集    

知识大全 DataGrid中嵌套使用Repeater

DataGrid中嵌套使用Repeater  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 DataGrid使用心得(附大量代码)

DataGrid使用心得(附大量代码)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为Data

知识大全 捕捉DataGrid的双击事件

捕捉DataGrid的双击事件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!<!StartF

知识大全 添加一个下拉框到DataGrid

添加一个下拉框到DataGrid  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本实例利用Pai

知识大全 DataGrid类的层次结构[2]

C#高级编程:DataGrid类的层次结构[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&n

知识大全 DataGrid类的层次结构[1]

C#高级编程:DataGrid类的层次结构[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&n