2015-04-28 2 views
0

У меня есть Gridview на странице ASP, привязанной к таблице SQL. Я настроил сетки, чтобы позволить несколько обновлений путем замены элементов управления этикетке по умолчанию с TemplateFields, используя подход, описанный здесь: Bulk Updates to Rows Bound to a GridViewASP.Net: Gridview запускает событие с ошибкой RowUpdating, которое не обрабатывалось

Все работало отлично, пока я не сделал изменения, чтобы связать Gridview запрос программным способом на странице загрузки (С целью сделать Gridview отображать разные данные в зависимости от пользователя, просматривающего страницу в данный момент), как описано здесь: Bind Gridview programmatically. После внесения этого изменения страницы Теперь выдает следующее сообщение об ошибке, когда пользователь вносит изменения и нажимает кнопку обновления:

В GridView 'GridView1 обстреляли RowUpdating событий, который не был обработан.

Кроме того, когда я пытаюсь сделать одно обновление строки, я получаю эту ошибку:

Сведения об исключении: System.Web.HttpException: обстреляли RowEditing Ивентов GridView «GridView1», который не был обработан.

Я прочитал много потоков по проблемам similair, но я не могу найти решение моей ошибки. Я не знаю, почему динамическое связывание Gridview вызывает ошибку в rowupdating. Оцените любую поддержку, чтобы решить эту проблему. Благодарю.

Вот код:

Public Class Input 
Inherits System.Web.UI.Page 

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

    If Not IsPostBack Then 

     gvbind() 


    End If 



End Sub 

Public Sub gvbind() 

    Dim SqlDataSource1 As New SqlDataSource() 
    SqlDataSource1.ID = "SqlDataSource1" 
    Me.Page.Controls.Add(SqlDataSource1) 
    SqlDataSource1.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString 

    SqlDataSource1.SelectCommand = "SELECT [ID], [Project], [Description], [CAPEX], [Team] FROM [CAPEX]" 
    'Add Conditional Statements to change view for users/Teams 
    'SqlDataSource1.SelectCommand = "SELECT [ID], [Project], [Description], [CAPEX] FROM [CAPEX] where [Team] = 'Team1'" 

    GridView1.DataSource = SqlDataSource1 
    GridView1.DataBind() 

End Sub 


Private tableCopied As Boolean = False 
Private originalDataTable As System.Data.DataTable 

Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound 
    If e.Row.RowType = DataControlRowType.DataRow Then 
     If Not tableCopied Then 
      originalDataTable = CType(e.Row.DataItem, System.Data.DataRowView).Row.Table.Copy() 
      ViewState("originalValuesDataTable") = originalDataTable 
      tableCopied = True 
     End If 
    End If 
End Sub 

Protected Sub Up_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Up.Click 
    originalDataTable = CType(ViewState("originalValuesDataTable"), System.Data.DataTable) 

    For Each r As GridViewRow In GridView1.Rows 
     If IsRowModified(r) Then GridView1.UpdateRow(r.RowIndex, False) 
    Next 

    ' Rebind the Grid to repopulate the original values table. 
    tableCopied = False 
    GridView1.DataBind() 

End Sub 



Protected Function IsRowModified(ByVal r As GridViewRow) As Boolean 
    Dim currentID As Integer 
    Dim currentProject As String 
    Dim currentDescription As String 
    Dim currentCAPEX As String 

    currentID = Convert.ToInt32(GridView1.DataKeys(r.RowIndex).Value) 

    currentProject = CType(r.FindControl("ProjectTextBox"), TextBox).Text 
    currentDescription = CType(r.FindControl("DescriptionTextBox"), TextBox).Text 
    currentCAPEX = CType(r.FindControl("CAPEXTextBox"), TextBox).Text 

    Dim row As System.Data.DataRow = _ 
     originalDataTable.Select(String.Format("ID = {0}", currentID))(0) 

    If Not currentProject.Equals(row("Project").ToString()) Then Return True 
    If Not currentDescription.Equals(row("Description").ToString()) Then Return True 
    If Not currentCAPEX.Equals(row("CAPEX").ToString()) Then Return True 
    Return False 
End Function 

Вот Markup:

<%@ Page Title="Input" Language="vb" MasterPageFile="~/Site.Master" AutoEventWireup="false" 
CodeBehind="Input.aspx.vb" Inherits="WebApplication5.Input" %> 

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"> 
</asp:Content> 
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> 
<h2> 
    Data Entry 
</h2> 
<p> 
    Enter Inputs Here<asp:TextBox runat="server" Text='<%# Bind ("Project") %>' 
     id="TextBox4"></asp:TextBox> 
&nbsp;<asp:Table ID="Entry" runat="server"> 
    </asp:Table> 
    <asp:Button ID="TestButton" runat="server" Text="Test" /> 
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
     AllowSorting="True" AllowPaging="True" datakeynames = "ID" Width="502px"> 

     <Columns> 
      <asp:CommandField ShowEditButton="True" /> 
      <asp:BoundField DataField="ID" readOnly = "true" HeaderText="ID" SortExpression="ID"/> 
      <asp:TemplateField HeaderText="Project" SortExpression="Project"> 
       <EditItemTemplate> 
        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Project") %>'></asp:TextBox> 
       </EditItemTemplate> 
       <ItemTemplate> 
        <asp:TextBox ID="ProjectTextBox" runat="server" MaxLength="30" 
         Text='<%# Bind("Project") %>'></asp:TextBox> 
       </ItemTemplate> 
      </asp:TemplateField> 
      <asp:TemplateField HeaderText="Description" SortExpression="Description"> 
       <EditItemTemplate> 
        <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Description") %>'></asp:TextBox> 
       </EditItemTemplate> 
       <ItemTemplate> 
        <asp:TextBox ID="DescriptionTextBox" runat="server" MaxLength="150" 
         Text='<%# Bind("Description") %>'></asp:TextBox> 
       </ItemTemplate> 
      </asp:TemplateField> 
      <asp:TemplateField HeaderText="CAPEX" SortExpression="CAPEX"> 
       <EditItemTemplate> 
        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("CAPEX") %>'></asp:TextBox> 
       </EditItemTemplate> 
       <ItemTemplate> 
        <asp:TextBox ID="CAPEXTextBox" runat="server" MaxLength="10" 
         Text='<%# Bind("CAPEX") %>'></asp:TextBox> 
       </ItemTemplate> 
      </asp:TemplateField> 
     </Columns> 
    </asp:GridView> 


    <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
     ConnectionString="<%$ ConnectionStrings:ConnectionString %>" 

     SelectCommand="SELECT [ID], [Project], [Description], [CAPEX] FROM [CAPEX]" 
     DeleteCommand="DELETE FROM [CAPEX] WHERE [ID] = @ID" 
     InsertCommand="INSERT INTO [CAPEX] ([ID], [Project], [Description], [CAPEX], [Team]) VALUES (@ID, @Project, @Description, @CAPEX, @Team)" 
     UpdateCommand="UPDATE [CAPEX] SET [Project] = @Project, [Description] = @Description, [CAPEX] = @CAPEX,[Team] = @Team WHERE [ID] = @ID"> 
     <DeleteParameters> 
      <asp:Parameter Name="ID" Type="String" /> 
     </DeleteParameters> 
     <InsertParameters> 
      <asp:Parameter Name="ID" Type="String" /> 
      <asp:Parameter Name="Project" Type="String" /> 
      <asp:Parameter Name="Description" Type="String" /> 
      <asp:Parameter Name="CAPEX" Type="Decimal" /> 
     </InsertParameters> 
     <UpdateParameters> 
      <asp:Parameter Name="Project" Type="String" /> 
      <asp:Parameter Name="Description" Type="String" /> 
      <asp:Parameter Name="CAPEX" Type="Decimal" /> 
      <asp:Parameter Name="ID" Type="String" /> 
      <asp:Parameter Name="Team" Type="String" /> 
     </UpdateParameters> 
    </asp:SqlDataSource> 
    <asp:Button ID="Up" runat="server" Text="Up" /> 
    <asp:SqlDataSource ID="SqlDataSource1" runat="server"></asp:SqlDataSource> 
    <asp:Table ID="Table1" runat="server" BorderWidth="1" BorderStyle="Solid"> 
    </asp:Table> 
</p> 

+1

Что-то вызывает «RowUpdating» и «RowEditing» для запуска, поэтому вам необходимо обработать их в коде. Кнопки с 'CommandName =" Update "или' CommandName = "Edit" 'будут делать что-то подобное. [Заместитель GridView-зажжены событийно-RowUpdating-который не был-ручкой-с-диез-код-Бэхи] (http://stackoverflow.com/questions/13016531/the-gridview-fired-event-rowupdating-which- wasnt-handled-c-sharp-code-behi? rq = 1) –

+0

Вы можете публиковать не только код, но и код asp. – xavigonza

+0

Я изменил название кнопки с «Обновить» на «Вверх», чтобы избежать срабатывания каких-либо встроенных функций, но у меня все еще есть проблема. – Sherif

ответ

1

Вы делаете вызов в Up_Click к 'GridView1.UpdateRow()'

С Документы MSDN:

Calling this method also raises the RowUpdated and RowUpdating events.

Так все, что вам нужно нужно сделать, это предоставить пустые обработчики

+0

Фностро, ты совершенно прав. Кажется, Gridview1.rowupdate также запускает события RowUpdated и Rowupdating. Хотя я должен признать, что я не полностью понимаю логику, почему эти события должны быть явно обработаны, если они являются встроенными функциями класса Gridview? В любом случае я добавил пустые обработчики следующим образом: Protected Sub Gridview1_RowUpdating (ByVal отправитель As Object, ByVal е Как System.Web.UI.WebControls.GridViewUpdateEventArgs) Ручки GridView1.RowUpdating End Sub – Sherif

+0

Protected Sub Gridview1_RowUpdated (ByVal отправителя в качестве объекта , ByVal e As System.Web.UI.WebControls.GridViewUpdatedEventArgs) Обрабатывает GridView1.RowUpdated End SubNow Когда я нажимаю кнопку обновления, я больше не получаю сообщение об ошибке «упущенное событие RowUpdating, которое не обрабатывалось». Ура! Однако теперь Gridview не обновляется с введенными новыми значениями. Если это имеет смысл, я подозреваю, что обработчики, которые я добавил, могут переопределить встроенную процедуру обновления? Любые другие идеи, почему его сейчас не обновляют? – Sherif

+0

BTW Я попытался дать кредит/голос за ваш ответ, а также очень полезные ответы, полученные от господ ниже, но, видимо, как новый член, я еще не имею этой привилегии :( – Sherif

0

Добавление к fnostro Ответим о GridView1.UpdateRow() повышении RowUpdated и RowUpdating, показывая кнопку редактирования, как вы делаете:

<asp:CommandField ShowEditButton="True" /> 

сгенерирует кнопку с CommandName="Edit". Нажатие этой кнопки вызывает событие RowEditing, которое вам также необходимо обработать в коде.

И как примечание стороны, так как ваша кнопка «Update» является за пределами GridView, то CommandName свойства не будет нести ответственность за автоматически запуская GridView события. Поэтому не только изменение ID с «Обновить» на «Вверх» не повлияет, но изменение CommandName также не было бы.

+0

@jf Чтобы уточнить, нажатие кнопки «Редактировать» приведет к событию RowEditing, вызовет GridView в режим редактирования и изменит поле Command чтобы показать 'Update' /' Cancel'. Нажатие кнопки «Update» приведет к появлению событий «RowUpdating» и «RowUpdated», и просто fyi - все клики CommandField повышают «RowCommand» – fnostro

+0

@fnostro - Правильно, спасибо.Поэтому, как только OP обрабатывает 'RowEditing', он столкнется с той же ошибкой с' RowUpdating' и 'RowUpdated', если нажата новая кнопка поля« Обновить », и ни одно из этих событий не будет обработано. –

+0

Код нового пользователя, похоже, изменился со вчерашнего дня, но если он теперь реализует SqlDataSource2 и Edit CommandField, ему больше не нужен «Up» или связанный с ним код IMO. Новичок должен также установить DataSourceID в SqlDataSource2 и сделать с ним. – fnostro

0

Я вижу, что определение SqlDataSource1 в codebehind не содержит определения UpdateCommand. Честно говоря, я всегда использовал подход SqlDataSource2, было бы столь же легко, как добавить DataSourceID="SqlDataSource2" и разметка будет:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    AllowSorting="True" AllowPaging="True" DataKeyNames = "ID" 
    DataSourceID="SqlDataSource2" Width="502px"> 

Таким образом, вы можете забыть о если GridView должен быть связан в постбэков. Если вы не разместите gridview внутри UpdatePanel, я бы сказал, что он должен быть связан, а затем If Not IsPostBack Then неправильно помещен.

Код <asp:TextBox runat="server" Text='<%# Bind ("Project") %>' id="TextBox4"></asp:TextBox> выглядит помещенным вне контроля привязки данных.

+0

Слово о UpdatePanels. Независимо от того, как вы инициализируете UpdatePanel, любой элемент управления, который запускает обратный вызов, внутри или снаружи, полный или частичный, вызывает _Full Page Lifecycle_. Это включает в себя всю привязку, которая автоматически возникает из-за того, что элементы управления базой данных имеют свои свойства DataSourceID. Панель обновления, когда настраивается для частичных обновлений, будет обновляться только после обновления, что означает передачу обратно в браузер, это собственное содержимое. – fnostro

Смежные вопросы