e4rthdog
e4rthdog

Reputation: 5233

How to control async textbox event

I have a textbox where its Leave event is like this:

private async void TxtLotTextLeave(object sender, EventArgs e)
{
    if (!isChecked)
    {
        isChecked = true;
        var mylength = BarcodeUtil.LotStripZeroes(txtLot.Text.Trim()).Length;
        var strippedLot = BarcodeUtil.LotStripZeroes(txtLot.Text.Trim());
        if (mylength > 0)
        {
            if (mylength.Between(16, 18) &&
                (strippedLot.StartsWith(AppState.LotOldStandardDigits) ||
                 strippedLot.StartsWith(AppState.LotStandardDigits)))
            {
                await GetLotData();
            }
            else
            {
                ShowAppMessage(AppMessages["WrongLot"], 0, Color.Black, Color.BlanchedAlmond);
                txtLot.Text = "";
                LotFocus(true);
            }
        }
    }
}

99% of the time i need this event to work like this.

BUT i only need when a specific button is clicking NOT to fire it.

Button click:

private void BtnClearClick(object sender, EventArgs e)
{
    ClearForm();
    LotFocus(true);
}

I tried the obvious to use a global bool variable and set it to false in click event and check it in leave but it doesnt work..I suspect that has to do with async?

Additional Info:

What i tried is to create a bool variable needTxtValidation and try to set it to false in various places like button click, textbox keypress, button mousedown, but it didnt work.

Upvotes: 0

Views: 107

Answers (1)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

Alright, here's the dirty way I managed to find. You need to inherit the Button, override the WndProc and expose a boolean which says whether currently processing MouseDown.

class ButtonEx : Button
{
    public bool IsInMouseDown { get; set; }
    protected override void WndProc(ref Message m)
    {
        const int WM_LBUTTONDOWN = 0x0201;
        try
        {
            if (m.Msg == WM_LBUTTONDOWN)
                IsInMouseDown = true;
            base.WndProc(ref m);
        }
        finally //Make sure we set the flag to false whatever happens.
        {
            if (m.Msg == WM_LBUTTONDOWN)//Required to fight with reentracy
                IsInMouseDown = false;
        }
    }
}

Then in your leave method

private async void TxtLotTextLeave(object sender, EventArgs e)
{
    if (yourButton.IsInMouseDown)
    {
        Console.WriteLine("Ignoring Leave");
        return;
    }
    ...
}

This works, however I won't guarantee it will continue to work always. You may need to address some corner cases or obvious thing which I've missed. That's a very hacky code, you are better off re-designing the logic.

Upvotes: 1

Related Questions