0
votes

On my C# windows form I have 3 textboxes that named textBuyPrice, textSell, and textMargin. The user can enter a Buy Price, and if they enter a Sell Price then the code will calculate the Margin for them. If the user enters a Margin then the code will enter a Sell Price. See these 2 bits of code that make up the margin calculations.

This code catches the enter of the cursor in the textbox and sets the current value to a variable.

private void textMargin_Enter(object sender, EventArgs e)
        {
        OriginalMarginValue = this.textMargin.Text;
        }

This code catches the leave event in the textbox and takes any changes, runs some calcs and updates any related fields.

private void textMargin_Leave(object sender, EventArgs e)
        {
        if (this.textMargin.Text != OriginalMarginValue)
            {
            Parts part = new Parts();
            decimal dcmBuy = part.RemoveDollarSign(this.textBuyPrice.Text);
            decimal dcmMargin = part.RemovePercentSign(this.textMargin.Text);
            decimal dcmSell = part.GetSellPrice(dcmBuy, dcmMargin / 100);
            string strSell = dcmSell.ToString("C");
            this.textSellPrice.Text = strSell; 
            }

        }

What is happening seems to be a loop between the Enter and Leave events. After the Leave event fires when I try and tab out of the textbox. The Enter event fires again and it will not let me tab out.

What is going on? Should I force the tab to set focus on another field?

The code above is identical to the textSellPrice code and I do not have the same problem in that textbox.

Thx

EDIT Here is the call stack as the code enters the Enter event for the 2nd time after trying to leave the textbox:

AutoShop.exe!AutoShop.formPartDetail.textMargin_Enter(object sender = {Text = "57.14 %"}, System.EventArgs e = {System.EventArgs}) Line 168 C# System.Windows.Forms.dll!System.Windows.Forms.Control.OnEnter(System.EventArgs e) + 0x88 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.NotifyEnter() + 0x1f bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.UpdateFocusedControl() + 0x195 bytes System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.AssignActiveControlInternal(System.Windows.Forms.Control value = {Text = "57.14 %"}) + 0x60 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ActivateControlInternal(System.Windows.Forms.Control control, bool originator = false) + 0x48 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.SetActiveControlInternal(System.Windows.Forms.Control value = {Text = "57.14 %"}) + 0x73 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ValidateThroughAncestor(System.Windows.Forms.Control ancestorControl, bool preventFocusChangeOnError) + 0x212 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.EnterValidation(System.Windows.Forms.Control enterControl) + 0x7c bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.UpdateFocusedControl() + 0x8a bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.AssignActiveControlInternal(System.Windows.Forms.Control value = {Text = ""}) + 0x60 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ActivateControlInternal(System.Windows.Forms.Control control, bool originator = false) + 0x48 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.SetActiveControlInternal(System.Windows.Forms.Control value = {Text = ""}) + 0x73 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.SetActiveControl(System.Windows.Forms.Control ctl) + 0x33 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ActiveControl.set(System.Windows.Forms.Control value) + 0x5 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.Select(bool directed, bool forward) + 0x1b bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.SelectNextControl(System.Windows.Forms.Control ctl, bool forward, bool tabStopOnly, bool nested, bool wrap) + 0x7e bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ProcessTabKey(bool forward = true) + 0x24 bytes
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ProcessDialogKey(System.Windows.Forms.Keys keyData = LButton | Back) + 0x71 bytes

1
Is there any kind of validation on textMargin? And does the OriginalMarginValue property have any code in the getter or setter that might be referencing the text box?ekolis
No validation, and the OriginalMarginValue is an int fieldRyan
Your code seem correct at first glance.Is the textbox inside another control (ie. groupbox etc.)? And if so, are similar events handled for that container? (enter and leave events are cascaded up the parent chain).user1693593
There are no parent controls etc and on the form there is only a load event.Ryan
Look at the call stack the 2nd time Enter fires to see how it got there.Hans Passant

1 Answers

0
votes

Try using Validating event for textbox. You will get options to cancel the validation as well.

e.g.

   private void textBox2_Validating(object sender, CancelEventArgs e)
        {
            if (DoSomething(textBox2))
            {
                textBox3.Text = textBox2.Text;
            }
            else
            {
                e.Cancel = true; //cancel the validation.
            }

        }