简体   繁体   中英

How can I make sure the textchanged event of a textbox is fired before the click event of a button?

I have textboxes and a button.

The button uses a value which is manipulated by the textbox textchanged event.

I don't want the button click event to be fired before the value is changed by the textbox changed event.

 void tprice_TextChanged(object sender, EventArgs e) {
      idtextbox tsender = (idtextbox)sender;
      decimal value = 0;
      decimal.TryParse(tsender.Text, out value);
      if (area_updates.ContainsKey(tsender.id)) { area_updates[tsender.id].price = value; }
      else { area_updates.Add(tsender.id, new area_update(tsender.id) { price = value }); }
      Session["area_updates"] = area_updates;
    }

 protected void bsave_Click(object sender, EventArgs e) {

    }

Afaik there is no way to ensure the event order TextChanged -> ButtonClick . You should use a different approach.

  1. Move the TextChanged logic into the ButtonClick event or
  2. Make the TextBox AutoPostBack=true , but this requires an additional postback

So i would suggest to put the logic into the ButtonClick - and remove the TextChanged event.

EDIT: As per another comment you made, if your textboxes are added and removed programatically you could also create a custom user control with your button and textbox, and implement this logic, then programatically add that user control. This is so one button and textbox will be related to each other and not know of others. I'm not sure of the context in which you want to do this, so this approach may not be the best.


Use a textboxIsDirty flag, which you set and unset in the two event handlers.

private bool tpriceIsDirty = false;

void tprice_TextChanged(object sender, EventArgs e) {
    tpriceIsDirty = true;
    // Do work
}

protected void bsave_Click(object sender, EventArgs e) {
    if (tpriceIsDirty)
    {
        tpriceIsDirty = false;
        // Do work
    }
}

As suggested in another answer, I would also do the current logic you have in the TextChanged method in the Click method. However, you can bind the tpriceIsDirty flag to the bsave.Enabled property to disable the button altogether if the textbox remains unchanged. Its nicer from a UX perspective. :)

Edit: as per a comment you made, you can also add and remove event handlers on the fly. A variation of this approach may be beneficial to you.

void tprice_TextChanged(object sender, EventArgs e) {
    if (bsave.Click == null)
    {
        bsave.Click += bsave_Click;
    }

    ....
}

protected void bsave_Click(object sender, EventArgs e) {
    bsave.Click = null;
}

Yes it's possible ... just have a look on below solution .. It's basically a trick created using javascript but enough powerful ..

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script>
        function EnsureNoSubmit(txt) {
            //alert('Ensured no submit');//test cases
            document.getElementById('<%=hdn.ClientID%>').value = false;
        }

        function isOkToSubmit() {
            var needSubmit = document.getElementById('<%=hdn.ClientID%>').value;            
            //if (needSubmit != '') {alert('No Submit now');}else {alert('Ok with Submit');}//test cases
            return needSubmit == '';
        }

        function MakeSureSubmit() {
            //alert('no submit revoked');//test cases
            document.getElementById('<%=hdn.ClientID%>').value = '';
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:HiddenField runat="server" ID="hdn" />
            <asp:TextBox AutoPostBack="true" runat="server" ID="txt" onchange="EnsureNoSubmit();" OnTextChanged="txt_TextChanged"></asp:TextBox>
            <asp:Button Text="Click Me" ID="btnClickMe" OnClientClick="return isOkToSubmit();" OnClick="btnClickMe_Click" runat="server" />
        </div>
    </form>
</body>
</html>

And on code behind side add only one line

protected void txt_TextChanged(object sender, EventArgs e)
{
    //Your code is here
    Page.ClientScript.RegisterStartupScript(this.GetType(),"Anything","MakeSureSubmit();",true);
}

It will work!!

  1. Enable the Save button's CausesValidation option.
  2. Call the focused editor's DoValidate method.
  3. Call the form's ValidateChildren method.

https://msdn.microsoft.com/de-de/library/ms158374(v=vs.110).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM