Gridview, почему все видимые строки установлены на грязные? - PullRequest
5 голосов
/ 30 апреля 2011

Я использую элемент управления 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>

Процедура тестирования следующая:
-Загрузить страницу.
-Измените что-нибудь в первом ряду.
-Нажмите кнопку Сохранить.

Ответы [ 2 ]

4 голосов
/ 05 мая 2011

Код, который вы разместили, выглядит хорошо.Мой тестовый код почти идентичен вашему, но я не могу дать нежелательных результатов, которые вы видите.

Самое существенное различие между вашим кодом и моим заключается в том, что у меня нет кода для вашей главной страницы.Моя главная страница является страницей по умолчанию, созданной VS 2008. Кроме этого, различия в SQL и базовой базе данных.В частности, я не использую хранимые процедуры, и я сделал разумные предположения относительно используемых типов данных: ID равно int, Status равно smallint, SheetDate равно Date, DateUpdatedDateTime, а все остальное varchar.

РЕДАКТИРОВАТЬ: Ваш SheetDate представляется просто часть даты базового значения DateTime из базы данных.Тот факт, что ваш запрос преобразует базовое значение данных для целей отображения, не имеет значения, поскольку представление сетки не может сказать, что оно получает измененное значение. КОНЕЦ РЕДАКТИРОВАНИЯ

Вот несколько советов по диагностике проблемы:

  • Тест без главной страницы или с очень простой фиктивной главной страницейгарантированно не будет сценариев, взаимодействующих с BulkEditGridView.Поскольку ToolkitScriptManager, по-видимому, находится на вашей главной странице, вам необходимо либо переместить элемент управления диспетчера сценариев на саму страницу, либо временно избавиться от элемента CalendarExtender, для которого требуется диспетчер сценариев.

  • Временно замените поле шаблона Status связанным полем данных, чтобы исключить возможность взаимодействия с DropDownList.Раскрывающийся список не вызвал проблем в моих тестах, но между вашим кодом и моим могут быть тонкие различия.

  • Если ни один из этих способов не помог, то возможная причина - проблема вВаша версия BulkEditGridView.

РЕДАКТИРОВАТЬ - Дополнительные предложения по диагностике:

  • На основании обследованияИсходный код для BulkEditGridView, похоже, что код правильно отслеживает, какие строки сетки являются «грязными».Следовательно, наиболее вероятная причина появления ложной грязной строки заключается в том, что один или несколько элементов управления в сетке неправильно обнаруживают изменение содержимого своих данных.Вы можете обнаружить это в отладчике, используя исходный код для BulkEditGridView, а не предварительно скомпилированную DLL.

  • Установите точку останова в начале HandleRowChanged, событиеобработчик, который обнаруживает изменения в любой ячейке сетки.Изучив параметр sender этого объекта в отладчике, вы можете определить, какие элементы управления в сетке претерпевают изменения значений.В частности, вы сможете сказать, какие элементы управления, если таковые имеются, неправильно запускают событие изменения значения.

  • После того, как вы определите, какие элементы управления неправильно сообщают об изменении их значения, вы можете сосредоточиться на , почему это происходит.

КОНЕЦ РЕДАКТИРОВАНИЯ

Некоторые другие предложения по улучшению кода следующие. Это не решит исходную проблему , но сделает код более чистым:

  • Во всех полях шаблона удалите ItemTemplate s.Они никогда не могут быть использованы, так как BulkEditGridView заставляет каждую строку находиться в состоянии редактирования.

  • В приведенном ниже коде вызов BindData() не требуется, поскольку исходные данные указываются в декларативной разметке, и, следовательно, элемент управления видом сетки автоматически связывает данные.

0 голосов
/ 02 мая 2011

Я не эксперт по элементу управления BulkEditGridView, но это то, что я нашел в записи в блоге Мэтта Дотсона

Возможно, вы не сможете узнать, что строка была обновлена, если вы не будете следить за изменениями в явном виде. Во-первых, для каждой строки добавьте обработчик изменений

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...