[Mono-winforms-list] NumericUpDown test case (with the right fileattached)

Jonathan Gilbert 2a5gjx302 at sneakemail.com
Sun Jun 12 11:38:42 EDT 2005


At 10:53 PM 11/06/2005 +1000, JBA wrote:
>Appologies, I sent the wrong file last time (please ignore the
>last email with the MonthCalendar.cs attached)
>
>Hey guys.
>
>Attached is the simplest NumericUpDown Value bug testcase I can
>come up with.
>Clicking on the test button changes the value from the minimum
>(1953) to 2004. Running this test case on windows (using MWF on
>.net framework) it takes 3 clicks of the test button for the
>value to change in the Numeric up down control. I don't know why
>this is though.
>
>JBA

I did some testing, and the problem seems to be a bug in mono's TextBox.
For one call to:

txtView.Text = value;

..the OnTextChanged event seems to be firing twice. The reason this causes
the problem is that UpDownBase uses a pair of flags to maintain the current
state and determine the correct behaviour. When the user types text into
the text box, the OnTextChanged event fires and the UserEdit property is
set to true. This property indicates that UpdateEditText should call
ParseEditText. To allow the controls to force an update without firing
ParseEditText, there is a property ChangingText. Subclasses of UpDownBase
can set this to true before assigning to the Text property, thereby
avoiding UserEdit being set to true. The logic is like this:

void OnTextBoxTextChanged(...)
{
  if (ChangingText)
    ChangingText = false; // Permit the subclass's change to the text box.
  else
    UserEdit = true;      // Recognize a change not requested by the subclass.
  ...
}

So, if the event fires twice, the first one consumes the ChangingText ==
true, and the second one then erroneously sets UserEdit to true.

I've taken a peek at the code for TextBox (and TextBoxBase and Control, the
base classes), and I think I see why this is happening. Basically,
TextBoxBase overrides Control.Text { set; } and does this:

base.Text = value;
OnTextChanged(EventArgs.Empty);

..at the end of the accessor. However, Control's own Text { set; } accessor
*also* calls OnTextChanged. I think the solution is fairly simple: remove
the call to OnTextChanged inside TextBoxBase's Text { set; } accessor. I
tested this locally and it did fix the problem :-) I don't know if this is
the correct fix or if it will have consequences elsewhere (though it does
seem right), but it should at least work as a work-around on your local
copy until Peter Bartok (in charge of TextBox) commits an official fix.

Jonathan Gilbert



More information about the Mono-winforms-list mailing list