I have run across an issue recently while incorporating AJAX into one of my applications. The issue demonstrates either my fundamental lack of understanding about how this technology works, or a problem in my implementation of it. I have created an bare-bones simple example to demonstrate what I'm seeing. I know how to remedy the problem, but I'd prefer the discussion center around *WHY* it's happening.
Here are the details. Consider a project with a default.aspx. That page has two controls, Button1 and PlaceHolder1. The project also contains as usercontrol, uc1.ascx, which simply contains a TextBox control, TextBox1. The click event of Button1 dynamically loads uc1 into the placeholder via the Page.LoadControl method. All I really want to do is set focus to to TextBox1 after the control is loaded. Without the UpdatePanel, I can do it two ways. I can either put TextBox1.Focus(); in UC1's page load event, or I can register a startup javascript to find the textbox and use its focus() method. Either way works fine. See example code below.
Now introduce UpdatePanel. Enclose Button1 and PlaceHolder1 in the same UpdatePanel. The result, no focus to the textbox. Move Button1 outside of the UpdatePanel, focus will work. Fundamental question is - WHY? Why does it matter where that button control is in relation to the Placeholder and UpdatePanel. I've done a lot of searching on this topic and I've found lots of questions but not many answers. Here's the code I'm using, to get focus to work correctly, move Button1 outside of the UpdatePanel:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Load UC1" OnClick="Button1_Click" />
<br />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
Button1_Click Event:
protected void Button1_Click (object sender, EventArgs e)
{
Control ctrl = new Control();
this.PlaceHolder1.Controls.Clear();
ctrl = Page.LoadControl("uc1.ascx");
ctrl.ID = "DynamicCtrl";
this.PlaceHolder1.Controls.Add(ctrl);
}
uc1.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="uc1.ascx.cs" Inherits="uc1" %>
UserControl 1 <br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
uc1.ascx.cs:
using System;
using System.Web.UI;
public partial class uc1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
//use either of these two lines in the example
//this.TextBox1.Focus();
ScriptManager.RegisterStartupScript(this, typeof(UserControl), "focus", "document.getElementById('DynamicCtrl_TextBox1').focus();", true);
}
}