M
mawi
Hi there,
When removing page children controls created dynamically
not in last-to-first order, the close button of the last
control looses its event wiring, even though the handler is
rewired on each postback. It needs one postback roundtrip
to "get it back".
Form has an "add panel" button. Using it I dynamically add
3 panels with a remove button on each, A B C, to the page.
I remove B. Remove button on C then looses its click event.
Clicking it will do nothing, but the roundtrip will cause
it to get the event wiring back. If instead, I click a
"roundtrip" asp button that does nothing except initiates a
roundtrip, it will also get it back, and clicking on it
will remove the panel as expected.
Below is the code if anyone wants to try it out. If anyone
has any idea on this, please offer it to me! Thanks!
/mawi
<%@ Page language="c#" AutoEventWireup="true" Trace="true" %>
<script runat="server">
void Page_Init()
{
if ( Session[ "PanelCount" ] == null )
{
Session[ "PanelCount" ] = 0;
AddPanel( null, null );
}
else
{
int panelCnt = (int)Session["PanelCount" ];
for ( int i = 0; i < panelCnt; i++ )
AddPanel();
}
}
void Page_Load()
{
Trace.Write( "loadloadload" );
Button b;
Panel p;
foreach ( Control c in ph.Controls )
{
p = c as Panel;
if ( p != null )
{
Trace.Write( "panel" );
if ( ( b = c.Controls[ 2 ] as Button ) != null )
{
Trace.Write( "button" );
try
{
b.Click -= new System.EventHandler(this.RemovePanel);
}
finally
{
b.Click += new System.EventHandler(this.RemovePanel);
}
}
}
}
}
void ChangeLabel(object sender, System.EventArgs e)
{
((sender as Button).Parent.Controls[ 0 ] as Label).Text
= "I got changed";
}
protected void AddPanel( object sender, System.EventArgs e )
{
AddPanel();
int ix = ph.Controls.Count - 1;
if ( ix < 0 )
ix = 0;
Label l1 = ph.Controls[ ix ].Controls[0] as Label;
Button b1 = ph.Controls[ ix ].Controls[1] as Button;
String cnt = (Session[ "PanelCount" ] = ((int)Session[
"PanelCount" ]) + 1).ToString();
// b1.Click += new System.EventHandler(this.ChangeLabel);
l1.Text = "Persist me " + cnt;
b1.Text = "Change label " + cnt;
b1 = ph.Controls[ ix ].Controls[2] as Button;
b1.Text = "Remove panel " + cnt;
}
private void AddPanel()
{
Panel p1 = new Panel();
ph.Controls.Add( p1 );
Button b1 = new Button();
p1.Controls.Add( new Label() );
p1.Controls.Add( b1 );
b1.Click += new System.EventHandler(this.ChangeLabel);
// comment this to try event persist
Button b = new Button();
p1.Controls.Add( b );
b.Click += new System.EventHandler(this.RemovePanel);
}
protected void RemovePanel(object sender, System.EventArgs e)
{
( sender as Button ).Parent.Parent.Controls.Remove( (
sender as Button ).Parent );
Session[ "PanelCount" ] = ((int)Session[ "PanelCount" ])
- 1;
}
protected void ReleaseSession(object sender,
System.EventArgs e)
{
Session.Abandon();
}
</script>
<html>
<body>
<form runat="server">
<asplaceHolder id="ph" runat="server" />
<asp:Button id="adder" Runat="server" OnClick="AddPanel"
Text="add panel" AccessKey="a" />
<asp:Button Runat="server" OnClick="ReleaseSession"
Text="Abandon session" />
<asp:Button Runat="server" Text="Roundtrip" />
</form>
</body>
</html>
When removing page children controls created dynamically
not in last-to-first order, the close button of the last
control looses its event wiring, even though the handler is
rewired on each postback. It needs one postback roundtrip
to "get it back".
Form has an "add panel" button. Using it I dynamically add
3 panels with a remove button on each, A B C, to the page.
I remove B. Remove button on C then looses its click event.
Clicking it will do nothing, but the roundtrip will cause
it to get the event wiring back. If instead, I click a
"roundtrip" asp button that does nothing except initiates a
roundtrip, it will also get it back, and clicking on it
will remove the panel as expected.
Below is the code if anyone wants to try it out. If anyone
has any idea on this, please offer it to me! Thanks!
/mawi
<%@ Page language="c#" AutoEventWireup="true" Trace="true" %>
<script runat="server">
void Page_Init()
{
if ( Session[ "PanelCount" ] == null )
{
Session[ "PanelCount" ] = 0;
AddPanel( null, null );
}
else
{
int panelCnt = (int)Session["PanelCount" ];
for ( int i = 0; i < panelCnt; i++ )
AddPanel();
}
}
void Page_Load()
{
Trace.Write( "loadloadload" );
Button b;
Panel p;
foreach ( Control c in ph.Controls )
{
p = c as Panel;
if ( p != null )
{
Trace.Write( "panel" );
if ( ( b = c.Controls[ 2 ] as Button ) != null )
{
Trace.Write( "button" );
try
{
b.Click -= new System.EventHandler(this.RemovePanel);
}
finally
{
b.Click += new System.EventHandler(this.RemovePanel);
}
}
}
}
}
void ChangeLabel(object sender, System.EventArgs e)
{
((sender as Button).Parent.Controls[ 0 ] as Label).Text
= "I got changed";
}
protected void AddPanel( object sender, System.EventArgs e )
{
AddPanel();
int ix = ph.Controls.Count - 1;
if ( ix < 0 )
ix = 0;
Label l1 = ph.Controls[ ix ].Controls[0] as Label;
Button b1 = ph.Controls[ ix ].Controls[1] as Button;
String cnt = (Session[ "PanelCount" ] = ((int)Session[
"PanelCount" ]) + 1).ToString();
// b1.Click += new System.EventHandler(this.ChangeLabel);
l1.Text = "Persist me " + cnt;
b1.Text = "Change label " + cnt;
b1 = ph.Controls[ ix ].Controls[2] as Button;
b1.Text = "Remove panel " + cnt;
}
private void AddPanel()
{
Panel p1 = new Panel();
ph.Controls.Add( p1 );
Button b1 = new Button();
p1.Controls.Add( new Label() );
p1.Controls.Add( b1 );
b1.Click += new System.EventHandler(this.ChangeLabel);
// comment this to try event persist
Button b = new Button();
p1.Controls.Add( b );
b.Click += new System.EventHandler(this.RemovePanel);
}
protected void RemovePanel(object sender, System.EventArgs e)
{
( sender as Button ).Parent.Parent.Controls.Remove( (
sender as Button ).Parent );
Session[ "PanelCount" ] = ((int)Session[ "PanelCount" ])
- 1;
}
protected void ReleaseSession(object sender,
System.EventArgs e)
{
Session.Abandon();
}
</script>
<html>
<body>
<form runat="server">
<asplaceHolder id="ph" runat="server" />
<asp:Button id="adder" Runat="server" OnClick="AddPanel"
Text="add panel" AccessKey="a" />
<asp:Button Runat="server" OnClick="ReleaseSession"
Text="Abandon session" />
<asp:Button Runat="server" Text="Roundtrip" />
</form>
</body>
</html>