0

After a form submits, it reverts to its original state (for the most part), and we want to have a "Reset" button that allows the user to start the page "afresh". I was hoping I could define and configure the HtmlButton in code:

HtmlButton btnStartNewDirPay = null;
. . .
private void CreateAndConfigureButtonStartNewDirectPayment()
{
    btnStartNewDirPay = new HtmlButton();
    btnStartNewDirPay.Attributes["type"] = "reset";
    btnStartNewDirPay.InnerHtml = "Start new Direct Pay";
    btnStartNewDirPay.ID = "btnStartNewDirPay";
} 

...and then instantiate it only on postback (after the form has submitted) like so:

if (Page.IsPostBack) 
{
    if (null == btnStartNewDirPay)
    {
        CreateAndConfigureButtonStartNewDirectPayment();
    }
    this.Controls.Add(btnStartNewDirPay); //this causes problems
}

But the last line (where the button is added to the page's (this's) Controls), it fails with:

System.Web.HttpException was unhandled by user code Message=Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.
Source=System.Web ErrorCode=-2147467259 StackTrace: at System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at System.Web.UI.Control.AddedControl(Control control, Int32 index) at DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.Page_Load(Object sender, EventArgs e) at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) at System.Web.UI.Control.OnLoad(EventArgs e) at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
InnerException:

I also tried creating/configuring the HtmlButton at the beginning (when IsPostBack was false), by adding the control to "this" from the git-go, like this:

private void CreateAndConfigureButtonStartNewDirectPayment()
{
    btnStartNewDirPay = new HtmlButton();
    btnStartNewDirPay.Attributes["type"] = "reset";
    btnStartNewDirPay.InnerHtml = "Start new Direct Pay";
    btnStartNewDirPay.ID = "btnStartNewDirPay";
    this.Controls.Add(btnStartNewDirPay);
} 

...and then hiding it via jQuery:

$(window).load(function () {
    . . .
        $('[id$=btnStartNewDirPay]').hide();
});

...but that also failed on the same line ("this.Controls.Add(btnStartNewDirPay);") in "CreateAndConfigureButtonStartNewDirectPayment()" with the same err msg as above, once IsPostBack is true.

So it won't allow me to instantiate and hide the HtmlButton at the beginning, and later show it when IsPostBack is true; Nor will it allow me to defer instantiation to when IsPostBack is true, it seems. Surely it's possible to have an element that displays after a postback but not prior to that...but how?

4

1 回答 1

1

Creating a new button is over kill here.

Just have the button on the view like so and make it visible=false.

<asp:Button id="btnStartNewDirPay" ClientIDMode="Static" Text="Reset" runat="server" Visible="False" />

Set its ClientIDMode to static so the id is easier to get via jQuery.

Then on post back at the end of the saving set the visible to true.

if(IsPostBack)
{
    ....
    btnStartNewDirPay.Visible = true;
}

On the front end then have a click listener

$(document).ready(function(){
    $("#btnStartNewDirPay").click(function(){
        //Reset inputs to default values.
    })
})
于 2015-08-10T21:44:06.860 回答