Gridview为什么所有可见行都设置为dirty

本文关键字:设置 dirty 为什么 Gridview | 更新日期: 2023-09-27 17:53:43

我使用BulkEditGridView控件如讨论http://roohit.com/site/showArc.php?shid=bbb62,它是完美的我的需要。我遇到的问题是,每当我保存时,每个可见行(我启用了分页)都会得到更新。逐步执行代码,我看到grid.DirtyRows.Count等于每页的条目数减去单击保存按钮时的1。

我找不到行设置为脏的地方。有什么建议吗?

我的后台代码只有这个:

using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Collections;
using System.Data.Common;
public partial class MSDS_MSDS_Admin_GridUpdate : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            gridMSDS.DataKeyNames = new String[] { "id" };
            gridMSDS.DataBind();
        }
    }
}

编辑:这是aspx代码。

<%@ Page Language="C#" MasterPageFile="~/MSDS/MSDS.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="GridUpdate.aspx.cs" Inherits="MSDS_MSDS_Admin_GridUpdate" Title="Untitled Page" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<%@ Register Assembly="RealWorld.Grids" Namespace="RealWorld.Grids" TagPrefix="cc2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="PageContent" runat="Server">
    <br />
    <asp:Button ID="btnSave" runat="server" Text="Save" Width="100%" />
    <cc2:BulkEditGridView ID="gridMSDS" runat="server" AllowPaging="True" AllowSorting="True"
        DataSourceID="sqlData" EnableInsert="False" InsertRowCount="1" PageSize="20"
        SaveButtonID="btnSave" AutoGenerateColumns="False">
        <Columns>
            <asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" Visible="false"
                ReadOnly="True" SortExpression="ID" />
            <asp:BoundField DataField="ChemicalTitle" HeaderText="ChemicalTitle" SortExpression="ChemicalTitle" />
            <asp:TemplateField HeaderText="SheetDate" SortExpression="SheetDate">
                <EditItemTemplate>
                    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SheetDate") %>' Width="85px"></asp:TextBox>
                    <cc1:CalendarExtender ID="TextBox1_CalendarExtender" runat="server" Enabled="True"
                        TargetControlID="TextBox1">
                    </cc1:CalendarExtender>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label2" runat="server" Text='<%# Eval("SheetDate") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="Filename" HeaderText="Filename" SortExpression="Filename" />
            <asp:BoundField DataField="Manufacturer" HeaderText="Manufacturer" SortExpression="Manufacturer" />
            <asp:BoundField DataField="UsageDept" HeaderText="UsageDept" SortExpression="UsageDept" />
            <asp:TemplateField HeaderText="Notes" SortExpression="Notes">
                <EditItemTemplate>
                    <asp:TextBox ID="TextBox5" runat="server" Text='<%# Bind("Notes") %>' TextMode="MultiLine"></asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label6" runat="server" Text='<%# Bind("Notes") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Status" SortExpression="Status">
                <EditItemTemplate>
                    <asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" DataTextField="DisplayValue"
                        DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
                    </asp:DropDownList>
                    <asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
                        SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
                        <SelectParameters>
                            <asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
                        </SelectParameters>
                    </asp:SqlDataSource>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" disabled="true"
                        BackColor="White" DataTextField="DisplayValue" DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
                    </asp:DropDownList>
                    <asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
                        SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
                        <SelectParameters>
                            <asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
                        </SelectParameters>
                    </asp:SqlDataSource>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Health" SortExpression="Health">
                <EditItemTemplate>
                    <center>
                        <asp:TextBox ID="TextBox2" runat="server" Style="text-align: center" Text='<%# Bind("Health") %>'
                            Width="25px"></asp:TextBox>
                    </center>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label3" runat="server" Text='<%# Bind("Health") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Fire" SortExpression="Fire">
                <EditItemTemplate>
                    <center>
                        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Fire") %>' Width="25px"></asp:TextBox></center>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label4" runat="server" Text='<%# Bind("Fire") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Reactivity" SortExpression="Reactivity">
                <EditItemTemplate>
                    <center>
                        <asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("Reactivity") %>' Width="25px"></asp:TextBox></center>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label5" runat="server" Text='<%# Bind("Reactivity") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="DateUpdated" HeaderText="DateUpdated" SortExpression="DateUpdated"
                ReadOnly="True" />
            <asp:BoundField DataField="UpdatedBy" ReadOnly="True" HeaderText="UpdatedBy" SortExpression="UpdatedBy" />
        </Columns>
    </cc2:BulkEditGridView>
    <asp:SqlDataSource ID="sqlData" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
        SelectCommand="SELECT [ID], [ChemicalTitle], dbo.dateOnly([SheetDate]) As [SheetDate], [Filename], [Manufacturer], [UsageDept], [Notes], isnull([Status], 4) as [Status], [Health], [Fire], [Reactivity], [DateUpdated], [UpdatedBy] FROM [msds_Sheets] ORDER BY [ChemicalTitle]"
        UpdateCommand="msds_UpdateSheet" UpdateCommandType="StoredProcedure">
        <UpdateParameters>
            <asp:Parameter Name="ID" Type="Int32" />
            <asp:Parameter Name="ChemicalTitle" Type="String" />
            <asp:Parameter Name="SheetDate" DbType="DateTime" />
            <asp:Parameter Name="Filename" Type="String" />
            <asp:Parameter Name="Manufacturer" Type="String" />
            <asp:Parameter Name="UsageDept" Type="String" />
            <asp:Parameter Name="Notes" Type="String" />
            <asp:Parameter Name="Status" Type="Int16" />
            <asp:Parameter Name="Health" Type="Int16" />
            <asp:Parameter Name="Fire" Type="Int16" />
            <asp:Parameter Name="Reactivity" Type="Int16" />
            <asp:ProfileParameter Name="UpdatedBy" Type="String" PropertyName="Username" />
        </UpdateParameters>
    </asp:SqlDataSource>
</asp:Content>

测试程序如下:
-加载页面。
-在第一行编辑一些东西。
-点击保存按钮

Gridview为什么所有可见行都设置为dirty

您发布的代码看起来很好。我的测试代码几乎与您的相同,但是我无法产生您所看到的不想要的结果。

你的代码和我的代码之间最显著的区别是我没有你的母版页的代码。我的主页是VS 2008创建的默认页面。除此之外,不同之处在于SQL和底层数据库。具体来说,我没有使用任何存储过程,并且我对所涉及的数据类型做出了合理的假设:IDint, Statussmallint, SheetDateDate, DateUpdatedDateTime,其他都是varchar

EDIT:您的SheetDate似乎只是数据库中底层DateTime值的日期部分。查询为显示目的而转换底层数据值的事实与此无关,因为网格视图无法判断它获得的是修改后的值。END OF EDIT

这里有一些诊断问题的建议:

  • 测试不带母版页,或带非常简单的虚拟母版页面就是保证不会有这样的脚本与BulkEditGridView相互作用。因为ToolkitScriptManager是显然在你的主页上,你会的需要移动脚本页本身的管理器控件,不然就暂时摆脱CalendarExtender元素,其中

  • 暂时替换Status带有绑定数据的模板字段场,消除可能性与DropDownList的交互。下拉列表没有引起我的测试有问题,但可能有注意你和别人之间的细微差别

  • 如果这些都没有帮助,那么可能的原因是您的

EDIT -附加诊断建议:

  • 基于对BulkEditGridView源代码的检查,似乎代码正确地跟踪了网格的哪些行是"脏的"。因此,产生伪脏行的最可能原因是网格中的一个或多个控件错误地检测到对其数据内容的更改。您可以使用BulkEditGridView的源代码在调试器中检测此问题,而不是使用预编译的DLL。

  • HandleRowChanged开始处设置一个断点,CC_20是检测网格中任何单元格中的变化的事件处理程序。通过在调试器中检查该对象的sender参数,您可以判断网格中的哪些控件正在进行值更改。特别是,您将能够判断哪些控件(如果有的话)错误地触发了值更改事件。

  • 一旦你确定了哪些控件错误地报告了它们的值发生了变化,你可以关注为什么会发生这种情况。

END OF EDIT

改进代码的其他一些建议如下。这些不能解决原来的问题,但会使代码更清晰:

  • 在所有模板字段中,删除ItemTemplate s。它们永远不能被使用,因为BulkEditGridView强制每一行都处于编辑状态。

  • 在后面的代码中,BindData()调用是不需要的,自源数据在声明中指定标记,因此网格视图控件将自动绑定数据。

我不是BulkEditGridView控件的专家,但这是我在Matt Dotson的博客条目中发现的

您可能无法知道该行已被更新,除非您显式地监视更改。首先,为每一行添加一个更改处理程序

protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
   {
      base.InitializeRow(row, fields);
      foreach (DataControlFieldCell cell in row.Cells)
      {
         if (cell.Controls.Count > 0)
         {
            AddChangedHandlers(cell.Controls);
         }
      }
   }

您可以使用以下代码段

private void AddChangedHandlers(ControlCollection controls)
   {
      foreach (Control ctrl in controls)
      {
         if (ctrl is TextBox)
         {
            ((TextBox)ctrl).TextChanged += new EventHandler(this.HandleRowChanged);
         }
         else if (ctrl is CheckBox)
         {
            ((CheckBox)ctrl).CheckedChanged += new EventHandler(this.HandleRowChanged);
         }
         else if (ctrl is DropDownList)
         {
            ((DropDownList)ctrl).SelectedIndexChanged += new EventHandler(this.HandleRowChanged);
         }
      }
   }

然后定义一个脏行列表并添加需要在那里更新的行(在事件处理程序中)

   private List<int> dirtyRows = new List<int>();
   void HandleRowChanged(object sender, EventArgs args)
   {
      GridViewRow row = ((Control) sender).NamingContainer as GridViewRow;
      if (null != row && !dirtyRows.Contains(row.RowIndex))
      {
         dirtyRows.Add(row.RowIndex);
      }
   }

最后,要提交更改,遍历所有脏行并保存更改

   public void Save()
   {
      foreach (int row in dirtyRows)
      {
         this.UpdateRow(row, false);
      }
      dirtyRows.Clear();
   }
这是你的ASPX代码
<asp:Button runat="server" ID="SaveButton" Text="Save Data" />
   <blog:BulkEditGridView runat="server" id="EditableGrid" DataSourceID="AdventureWorks" AutoGenerateColumns="False" DataKeyNames="LocationID" SaveButtonID="SaveButton" >
      <Columns>
         <asp:BoundField DataField="LocationID" HeaderText="LocationID" InsertVisible="False" ReadOnly="True" SortExpression="LocationID" />
         <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
         <asp:BoundField DataField="Availability" HeaderText="Availability" SortExpression="Availability" />
         <asp:BoundField DataField="CostRate" HeaderText="CostRate" SortExpression="CostRate" />
      </Columns>
   </blog:BulkEditGridView>