views:

426

answers:

6

I have a TextBox, which I use for both data input and display. A user can select items from a list and for each item there is a corresponding text which is displayed in the TextBox when the item is selected.

The user can edit this textbox, thus changing the list item's correponding text.

My problem is this: I use the TextChanged event to detect when the user enters some text and I update the internal variables in the event handler, however this event handler is called when I programmatically change the values of the textbox too. I want this handler only to be called when the User changes the textbox. How can I achieve this?

edit: I have the same problem a combo box as well.

+1  A: 

The TextChanged event is invoked whenever the TextBox changes its Text property, which can be achieved via modifying the Text property, or when the user directly changes the text, there are other events which are more likely usable for the scenario you are trying to achieve.

  • KeyPress: Raised whenever the user pulses a key
  • KeyDown: Raised whenever a Key is pulled down
  • KeyUp: Raised whenever a Key is pulled up (released)

Hope it helps

Jhonny D. Cano -Leftware-
This is solution problematic. When the user pastes some text by right clicking, paste, then no Key* eventhandler is fired.
Richard J. Terrell
I've been known to use Validating or Leave for this type of thing
SnOrfus
+1  A: 

You could set a flag in the programatic updates, and in the event handler exit early if the flag is set.

But if you use databinding, then the variables and the gui are synchronized automatically, which avoids this problem all together.

Jason Coyne
+2  A: 

The handler will always be called - no way disable it that I'm aware of. However you can simply set a flag in your class to indicate the you've programatically changed the state and should ignore the next event.

_updating = true;
_textBox.Text = "New Text";  

...      

_textBox_TextChanged( object sender, EventArgs e )
{
    if( _updating ) { _updating = false; return; }
    // Do something special with the new text.
}

You might also try creating your textbox control and overriding the Text property to provide your own custom logic.

class MyTextBox : TextBox
{
    public overrides string Text{ 
        get{ return base.Text; }
        set{
            if( value == Text ) return;
            _updating = true;
            base.Text = value;
            _updating = false;
           }
    }
}
Paul Alexander
I have tried it, but this is problematic, because when the new list item contains the same text value then the TextChanged is not called and next time the TextChanged is not called when it really should have been.
Richard J. Terrell
In that case you'll want to create an UpdateText method that you use to set the state instead of assigning it to the Text property directly. That method could check to see if i'ts the same value and discard it.
Paul Alexander
A: 

Do you mean you want the second textbox to display something which depends on what's in the first textbox, but ONLY if the user did set it ?

Could you be more specific about what you are trying to achieve? It seems to me that your UI design may be confusing for the user, since the text in B is sometimes related to A, and sometimes not.

If you still want to do it, the typical way to go is to use an updating flag, as proposed in other answers.

Brann
A: 

Check for focus on the textbox. If it does not have focus, it means the user isn't editing it.

Elroy
But if it does have focus, it does not mean the code isn't editing it.
Ishmaeel
+4  A: 

You can use the Latch pattern: see Rein in runaway events with the "Latch"

Igor Brejc
clearly the best approach so far
Richard J. Terrell