Monday, March 26, 2012

Access controls added dinamically?

Hi:
I trying to access to controls in updatepanel that I createddinamically before with atlas too, and I allways get the error that thecontrol does not exist.
Is there any way to do this?
Thanks so much.Do you have some sample source you can post? In which event handler are you trying to access the controls?
I was tried this with the code in the examples section. With SimpleList1_edit.aspx exactly.
I add a new textbox and a new button to panel3 when I click button ,and it works perfect, but when I click the new button and go to thecode for the code onclick then the findcontrol never finds the controlin the panel. I tried with find in the whole page and only in the panel and never works. This is the code:

<%@. Page Language="C#" %>

<%@. Import Namespace="System.Data" %>
<%@. Import Namespace="System.Data.SqlClient" %>

<script runat="server">

protected void Page_Load(object sender, EventArgs e)
{
TimerMessage.Text = DateTime.Now.ToLongTimeString();
if (!IsPostBack)
{
ViewState["CurrentTab"] = "0";
}
}


protected void AddnewBtn_click2(object sender, EventArgs e)
{
TextBox txtbox = (TextBox)FindControl("newtxtbox");
idlbl.Text = txtbox.Text;
panel3.Update();
}
protected void AddnewBtn_click(object sender, EventArgs e)
{


TextBox txtbox = new TextBox();
txtbox.ID = "newtxtbox";
Button btn = new Button();
btn.ID = "newbtn";
btn.OnClientClick = "AddnewBtn_click2";
panel3.Controls.Add(txtbox);
panel3.Controls.Add(btn);
btn.Text = "Read new textbox value";
panel3.Update();

}
protected string FormatPriority(int priority)
{
switch (priority)
{
case 1:
return "Low";
case 2:
return "Medium";
default:
return "High";
}
}

protected string FormatDone(bool isDone)
{
return isDone == true ? "Yes" : "No";
}

protected void Done_CheckedChanged(object sender, EventArgs e)
{
CheckBox cbx = (CheckBox)sender;
GridViewRow row = (GridViewRow)cbx.NamingContainer;
using (SqlConnection cn =newSqlConnection(ConfigurationManager.ConnectionStrings["SimpleListsConnectionString"].ConnectionString))
{
cn.Open();
SqlCommand cmd = new SqlCommand(
"UPDATE Lists SET IsComplete = @.IsComplete WHERE ListId = @.ListId",cn);
cmd.Parameters.Add("IsComplete", cbx.Checked);
cmd.Parameters.Add("ListId", ListGrid.DataKeys[row.RowIndex].Value);
cmd.ExecuteNonQuery();
}
ListGrid.DataBind();
}

protected void Select_Command(object sender, CommandEventArgs e)
{
ListDataSource.SelectParameters["IsComplete"].DefaultValue =
e.CommandArgument.ToString();
if (e.CommandName == "show")
SearchText.Text = "";
ViewState["CurrentTab"] = e.CommandArgument;
panel2.Update();
}

protected void Page_PreRender(object sender, EventArgs e)
{
int i = int.Parse(ViewState["CurrentTab"].ToString());
ActiveButton.CssClass = i == 0 ? "activeTab" : "tab";
CompletedButton.CssClass = i == 1 ? "activeTab" : "tab";
AllButton.CssClass = i == -1 ? "activeTab" : "tab";
SearchTab.Attributes["class"] = i == -2 ? "activeTab" : "tab";
}
protected void Page_ErrorHandler(object sender, PageErrorEventArgs e)
{
e.ErrorMessage = "Exception at " + DateTime.Now.ToString() +
"; Error Message: " + e.Error.Message;
}

</script>

<!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 id="Head1" runat="server">
<link href="http://links.10026.com/?link=StyleSheet.css" rel="stylesheet" type="text/css" />
<title>Partial Rendering</title>


</head>
<body>
<form id="f1" runat="server">
<atlas:ScriptManagerID="ScriptManager1" EnablePartialRendering="true"OnPageError="Page_ErrorHandler" runat="server">
<ErrorTemplate>
<div style="width: 450px; height: 300px; padding: 10px; border:solid 3px black; background: #ffd; text-align: left;">
<h1>Server Error</h1>
<p>An unhandled exception with the following message has occuredon the server:</p>
<p><span id="errorMessageLabel"runat="server"></span></p>
<p><input id="okButton" type="button" value="OK"runat="server"/></p>
</div>
</ErrorTemplate>
</atlas:ScriptManager>
<atlas:UpdateProgress runat="server" id="updateProgress1">
<ProgressTemplate>
<div style="width: 450px; height:300px;position:absolute; padding: 10px; border: solid 3px black;background: #ffd; text-align: left;">
<img src="http://pics.10026.com/?src=Progress.gif" /> Contacting Server...
<button id="abortButton">Stop</button>
</div>
</ProgressTemplate>
</atlas:UpdateProgress>
<div>
<div id="top">

</div>
<div class="ContentContainer">
<div id="header">
<div id="ServerMessage">
<span class="controlLabel">Server Time:</span>
<asp:Label ID="TimerMessage" runat="server">n/a</asp:Label><asp:Button ID="UpdateTimerMessageBtn" Text="Update" runat="server"/>
</div>
<span class="title"><a href="http://links.10026.com/?link=Default.aspx">SimpleList</a> > Standard Server Page</span>
</div>
<div class="tabs">

<atlas:UpdatePanel ID="panel1" runat="serveR" Mode="Conditional">
<ContentTemplate>
<span class="controlLabel">Show:</span>
<asp:LinkButton ID="ActiveButton" Text="Active" CommandName="show"CommandArgument="0" OnCommand="Select_Command" runat="server" />
<asp:LinkButton ID="CompletedButton" Text="Completed"CommandName="show" CommandArgument="1" OnCommand="Select_Command"runat="server" />
<asp:LinkButton ID="AllButton" Text="All" CommandName="show"CommandArgument="-1" OnCommand="Select_Command" runat="server" />
<span class="controlLabel leftSpace">Search:</span>
<span id="SearchTab" runat="server">
<asp:TextBox ID="SearchText" CssClass="filterdropdown" Width="150px"runat="server" />
<asp:Button ID="SearchBtn" CssClass="topButtons" Text=" >> "
CommandName="search" CommandArgument="-2" OnCommand="Select_Command"runat="server" />
</span>
</ContentTemplate>
</atlas:UpdatePanel>
<!-- Add a closing UpdatePanel tag below here. -->
</div>
<div id="list">

<atlas:UpdatePanel ID="panel2" runat="server" Mode="Conditional">
<ContentTemplate>
<asp:GridView ID="ListGrid" BorderWidth="0px"AutoGenerateColumns="False" DataKeyNames="ListId"
DataSourceID="ListDataSource" AllowPaging="True" AllowSorting="True"EnableViewState="False"
GridLines="None" runat="server">
<Columns>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"CausesValidation="True" CommandName="Update"
Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server"CausesValidation="False" CommandName="Cancel"
Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server"CausesValidation="False" CommandName="Edit"
Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="DeleteBtn" runat="server"CausesValidation="False" CommandName="Delete"
Text="Delete"></asp:LinkButton>
</ItemTemplate>
<ControlStyle CssClass="buttons" />
<HeaderStyle CssClass="commands" />
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="List"SortExpression="Name">
<ControlStyle CssClass="name_edit" />
<ItemStyle CssClass="name" />
<HeaderStyle CssClass="name" />
</asp:BoundField>
<asp:TemplateField HeaderText="Priority"SortExpression="Priority">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" Width="75"SelectedValue='<%# Bind("Priority") %>'
runat="server">
<asp:ListItem Text="High" Value="3" />
<asp:ListItem Text="Medium" Value="2" />
<asp:ListItem Text="Low" Value="1" />
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="pri" Text='<%# FormatPriority((int)Eval("Priority")) %>' runat="server" />
</ItemTemplate>
<ItemStyle CssClass="priority" />
<HeaderStyle CssClass="priority" />
</asp:TemplateField>
<asp:BoundField DataField="DateCreated"DataFormatString="{0:MM/dd/yyyy}" HtmlEncode="False"
HeaderText="Started" ReadOnly="True" SortExpression="DateCreated">
<ItemStyle CssClass="started" />
<HeaderStyle CssClass="started" />
</asp:BoundField>
<asp:TemplateField HeaderText="Completed"SortExpression="IsComplete">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" Checked='<%#Bind("IsComplete") %>' />
</EditItemTemplate>
<ItemStyle CssClass="iscomplete" />
<HeaderStyle CssClass="iscomplete" />
<ItemTemplate>
<asp:Label ID="Done" Text='<%# FormatDone((bool)Eval("IsComplete")) %>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<span id="Empty">No lists</span>
</EmptyDataTemplate>
</asp:GridView>
</ContentTemplate>
<Triggers>
<atlas:ControlEventTrigger ControlID="AddListBtn" EventName="Click"/>
</Triggers>
</atlas:UpdatePanel>
<!-- Add a closing UpdatePanel tag below here. -->
</div>
<div id="AddNew">

<atlas:UpdatePanel ID="panel3" Mode="Conditional" runat="server">
<ContentTemplate>
<span>Add New List:</span>
<asp:TextBox ID="AddItemTxt" CssClass="newitem"runat="server"></asp:TextBox>
<asp:Button ID="AddnewBtn" runat="server" OnClick="AddnewBtn_Click"Text="Add" />
</ContentTemplate>
<Triggers>
<atlas:ControlEventTrigger ControlID="AddnewBtn" EventName="Click"/>
</Triggers>
</atlas:UpdatePanel>

</div>


</div>
</div>

<asp:SqlDataSourceID="ListDataSource" runat="server" ConnectionString="<%$ConnectionStrings:SimpleListsConnectionString %>"
SelectCommand="SELECT ListId, Name, Priority, IsComplete, DateCreated
FROM Lists
WHERE (@.IsComplete = -1)
OR (@.IsComplete in (0, 1) AND IsComplete = @.IsComplete)
OR (@.IsComplete = -2 AND Name LIKE '%' + @.SearchText + '%')"
UpdateCommand="UPDATE Lists
SET Name=@.Name, IsComplete=@.IsComplete, Priority=@.Priority
WHERE ListId = @.ListId"
DeleteCommand="DELETE FROM Lists WHERE ListId = @.ListId">
<SelectParameters>
<asp:Parameter Name="IsComplete" Type="Int32" DefaultValue="0" />
<asp:ControlParameter Name="SearchText" Type="string"ControlID="SearchText"
PropertyName="Text" ConvertEmptyStringToNull="false" />
</SelectParameters>
</asp:SqlDataSource>

</form>
<hr />
</body>
</html
Thanks for the help.

I've been wondering about this as well. I'd really, really like the ability to do this. I came up with a short test page to validate the issue outside of my site.

The code for the test page is below. Run this, click "Add Control" and a label will be added to the placeholder control. Click "Refresh" and watch the label control vanish. You can also validate in the debugger that the label control added to the placeholder has disappeared (that is, it's not in the controls collection at Page_Load time()).

Is there something obvious I'm overlooking?

--

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><script runat="server"> protected void Page_Load(object sender, EventArgs e) { } protected void Add_OnCommand(object sender, CommandEventArgs e) { Label lab = new Label(); lab.Text = "Dynamically added label"; TestPlaceHolder.Controls.Add(lab); } protected void Refresh_OnCommand(object sender, CommandEventArgs e) { }</script><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Dynamically added control test</title></head><body> <form id="form1" runat="server"> <atlas:ScriptManager ID="ScriptManager1" runat="server" /> <atlas:UpdatePanel ID="TestPanel" runat="server"> <ContentTemplate> <asp:PlaceHolder ID="TestPlaceHolder" runat="server"></asp:PlaceHolder> <asp:Button ID="TestAddButton" runat="server" Text="Add Control" OnCommand="Add_OnCommand" /> <asp:Button ID="Refresh" runat="server" Text="Refresh" OnCommand="Refresh_OnCommand" /> </ContentTemplate> </atlas:UpdatePanel> </form></body></html>

^^^ Nevermind. My example didn't state the case correctly. I went back and fixed it and found everything was fine with values updating on dynamic controls.

The problem was in my site with an off-by-one error in control names. With the names corrected, everything is fine.

No comments:

Post a Comment