TextBoxes in UpdatePanel are causing PageRequestManagerServerErrorException
I'm trying to create a page that has some information in databound labels with and edit button. When the edit button is clicked, the information is replaced with TextBoxes bound to the same data. The data can then be modified, saved back to the DB and the TextBoxes replaced with updated Labels.
To start with, and to keep things simple, all I have is an UpdatePanel
with a DataList
and two buttons: EditButton
and CancelButton
(CancelButton
is hidden by default). The DataList
's ItemTemplate
has two Panels: ViewPanel
and EditPanel
(EditPanel
is hidden by default). When EditButton
is clicked, I hide EditButton
and the DataList
's Items
' ViewPanel
, and show CancelButton
and the DataList
's Items
' EditPanel
.
CancelButton
button will not work, throwing a PageRequestManagerServerErrorException
.
Through some fiddling, I worked out this happens because there are databound text boxes on the EditPanel
. If I don't bind data to the text boxes, everything works perfectly. Why doesn't this work?
Here's my code:
UpdatePanelTest.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UpdatePanelTest.aspx.cs" Inherits="WebLetterViewer.UpdatePanelTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
<asp:SqlDataSource ID="AllLettersDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:ORMSTestConnectionString %>"
SelectCommand="SELECT * FROM [Letters] WHERE ([id] = @id)">
<SelectParameters>
<asp:ControlParameter ControlID="HiddenLetterID" DefaultValue="1" Name="id" PropertyName="Value" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
<asp:HiddenField ID="HiddenLetterID" runat="server" Value="1" />
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:DataList ID="LettersDataList" runat="server" DataSourceID="AllLettersDataSource">
<ItemTemplate>
<asp:Panel ID="ViewPanel" runat="server">
<h2>Data1:</h2>
<asp:Label ID="data1Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px" Text='<%# Eval("data1") %>' Width="500px" />
<h2>data2:</h2>
<asp:Label ID="data2Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px" Text='<%# Eval("data2") %>' Width="500px" />
<h2>data3:</h2>
<asp:Label ID="data3Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px" Text='<%# Eval("data3") %>' Width="500px" />
</asp:Panel>
<asp:Panel ID="EditPanel" runat="server" Visible="False">
<h2>data1:</h2>
<asp:TextBox ID="data1TextBox" runat="server" Height="100px" Text='<%# Eval("data1", "{0}") %>' TextMode="MultiLine" Width="500px"></asp:TextBox>
<h2>data2:</h2>
<asp:TextBox ID="data2TextBox" runat="server" Height="100px" Text='<%# Eval("data2", "{0}") %开发者_运维百科>' TextMode="MultiLine" Width="500px"></asp:TextBox>
<h2>data3:</h2>
<asp:TextBox ID="data3TextBox" runat="server" Height="100px" Text='<%# Eval("data3", "{0}") %>' TextMode="MultiLine" Width="500px"></asp:TextBox>
</asp:Panel>
</ItemTemplate>
</asp:DataList>
<asp:Button ID="EditButton" runat="server" onclick="EditButton_Click" Text="Edit" />
<asp:Button ID="CancelButton" runat="server" onclick="CancelButton_Click" Text="Cancel" Visible="False" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
UpdatePanelTest.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebLetterViewer{
public partial class UpdatePanelTest : System.Web.UI.Page{
protected void Page_Load(object sender, EventArgs e){
}
protected void EditButton_Click(object sender, EventArgs e){
foreach (DataListItem item in LettersDataList.Items){
item.FindControl("ViewPanel").Visible = false;
item.FindControl("EditPanel").Visible = true;
}
EditButton.Visible = false;
CancelButton.Visible = true;
UpdatePanel1.Update();
}
protected void CancelButton_Click(object sender, EventArgs e){
foreach (DataListItem item in LettersDataList.Items){
item.FindControl("ViewPanel").Visible = true;
item.FindControl("EditPanel").Visible = false;
}
EditButton.Visible = true;
CancelButton.Visible = false;
UpdatePanel1.Update();
}
}
}
Put your EditPanel
in a EditItemTemplate and use Commands
, you are not using this control the way it was designed to be used:
How to: Allow Users to Edit Items in DataList Web Server Controls
Markup:
<asp:SqlDataSource ID="AllLettersDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:ORMSTestConnectionString %>"
SelectCommand="SELECT * FROM [Letters] WHERE ([id] = @id)">
<SelectParameters>
<asp:ControlParameter ControlID="HiddenLetterID" DefaultValue="1" Name="id" PropertyName="Value"
Type="Int32" />
</SelectParameters>
<!--change this -->
UpdateCommand="UPDATE [Categories] SET [CategoryName] = @CategoryName, [Description]
= @Description WHERE [CategoryID] = @original_CategoryID">
<UpdateParameters>
<asp:Parameter Name="CategoryName" Type="String" />
<asp:Parameter Name="Description" Type="String" />
<asp:Parameter Name="original_CategoryID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:DataList ID="LettersDataList" runat="server" DataSourceID="AllLettersDataSource"
OnEditCommand="LettersDataList_EditCommand" OnCancelCommand="LettersDataList_CancelCommand"
OnUpdateCommand="LettersDataList_UpdateCommand">
<ItemTemplate>
<asp:Panel ID="ViewPanel" runat="server">
<h2>
Data1:</h2>
<asp:Label ID="data1Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px"
Text='<%# Eval("data1") %>' Width="500px" />
<h2>
data2:</h2>
<asp:Label ID="data2Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px"
Text='<%# Eval("data2") %>' Width="500px" />
<h2>
data3:</h2>
<asp:Label ID="data3Label" runat="server" BorderStyle="Solid" BorderWidth="1px" Height="100px"
Text='<%# Eval("data3") %>' Width="500px" />
</asp:Panel>
<asp:Button ID="EditButton" runat="server" CommandName="edit" Text="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Panel ID="EditPanel" runat="server">
<h2>
data1:</h2>
<asp:TextBox ID="data1TextBox" runat="server" Height="100px" Text='<%# Eval("data1", "{0}") %>'
TextMode="MultiLine" Width="500px"></asp:TextBox>
<h2>
data2:</h2>
<asp:TextBox ID="data2TextBox" runat="server" Height="100px" Text='<%# Eval("data2", "{0}") %>'
TextMode="MultiLine" Width="500px"></asp:TextBox>
<h2>
data3:</h2>
<asp:TextBox ID="data3TextBox" runat="server" Height="100px" Text='<%# Eval("data3", "{0}") %>'
TextMode="MultiLine" Width="500px"></asp:TextBox>
</asp:Panel>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="update">
Save
</asp:LinkButton>
<asp:Button ID="CancelButton" runat="server" CommandName="cancel" Text="Cancel" Visible="False" />
</EditItemTemplate>
</asp:DataList>
Code-behind:
protected void LettersDataList_EditCommand(object source, DataListCommandEventArgs e)
{
LettersDataList.EditItemIndex = e.Item.ItemIndex;
LettersDataList.DataBind();
}
protected void LettersDataList_CancelCommand(object source,
DataListCommandEventArgs e)
{
LettersDataList.EditItemIndex = -1;
LettersDataList.DataBind();
}
protected void LettersDataList_UpdateCommand(object source,
DataListCommandEventArgs e)
{
//change this to your database needs
//String categoryID =
// LettersDataList.DataKeys[e.Item.ItemIndex].ToString();
//String categoryName =
// ((TextBox)e.Item.FindControl("textCategoryName")).Text;
//String description =
// ((TextBox)e.Item.FindControl("textDescription")).Text;
//SqlDataSource1.UpdateParameters["original_CategoryID"].DefaultValue
// = categoryID;
//SqlDataSource1.UpdateParameters["categoryName"].DefaultValue
// = categoryName;
//SqlDataSource1.UpdateParameters["Description"].DefaultValue
// = description;
//SqlDataSource1.Update();
LettersDataList.EditItemIndex = -1;
LettersDataList.DataBind();
}
精彩评论