How to add persistent dynamic controls based on user input (not on initial page load)
I am familiar with creating and persisting dynamic controls on the first load of a page and on subsequent postbacks but I am having trouble with the following user initiated scenario...
In my demo I have a placeholder, two buttons and a literal
<div>
<asp:PlaceHolder ID="phResponses" runat="server" />
</div>
<div>
<asp:Button ID="btnAdd" Text="Add" runat="server" OnClick="Add"/>
<asp:Button ID="btnInspect" Text="Inspect" runat="server" OnClick="Inspect"/>
</div>
<div>
<asp:Literal ID="litResult" runat="server"/>
</div>
I want the user to be able to click the add button to provide a response so I have...
protected void Page_Init(object sender, EventArgs e)
{
BuildControls();
}
protected void Add(object sender, EventArgs e)
{
BuildControls();
}
protected void BuildControls()
{
phResponses.Controls.Add(new LiteralControl { ID = "response_" + _Count.ToString() });
_Count++;
}
_Count is a static member variable to enable m开发者_如何学Pythone to have unique ids for the new controls. I realise I need to rebuild the dynamic controls on Page_Init but the problem is that I end up with 2 new Literal controls on every postback. Also if any Text property is put into the new controls it is lost when the controls are rebuilt.
So how do I avoid adding multiple controls and how do I persist newly added properties when rebuilding these controls?
I use the following to inspect the responses
protected void Inspect(object sender, EventArgs e)
{
foreach (var control in phResponses.Controls)
{
if (control is LiteralControl)
{
litResults.Text += "<p>" + control.Text + " : " + control.ID + "</p>";
}
}
}
Which itself adds another unwanted control because of the rebuilding on Page_Init
I'd not sure that I quite understand what you're asking, but it looks like you just want to ensure that BuildControls
is only called once per lifecycle. You could do that by making the following changes:
- Add a new
private bool _isControlsBuilt = false;
. - Change
Page_Init
to check_isControlsBuilt
before callingBuildControls
. - Set
_isControlsBuilt
totrue
withinBuildControls
. - Make sure that
BuildControls
occurs earlier in the page lifecycle thanPage_Init
.
As for losing the values of controls on postback, it'll be that they're never hitting the viewstate. I'm not sure if it'd work, but my first guess would be to add a line to the end of BuildControls
to call Page.RegisterRequiresControlState
:
protected void BuildControls()
{
LiteralControl newLiteral = new LiteralControl { ID = "response_" + _Count };
this.RegisterRequiresControlState(newLiteral);
phResponses.Controls.Add(newLiteral);
_Count++;
_isControlsBuilt = true;
}
If that doesn't work (which might imply that it's the _view_state, not the _control_state that matters to you here), you may need to look at rolling your own viewstate. I wrote about how to do that in my answer to #3854193, which you might find useful.
精彩评论