Adding leading zeros to NumericUpDown Control

J

Joe Cool

I am trying to force a numericupdown control to display leading zeros.
The maximum is less than 100, so the displayed value will always be a
two digit number or less. So I have overridden the OnValueChanged
Event with the following code;

protected override void OnValueChanged(EventArgs e)
{
base.OnValueChanged(e);
if (Value < 9)
Text = Value.ToString("00");
}


But it doesn't work. Can anyone spot the problem?
 
C

Cor Ligthert[MVP]

Joe,

Why not simple the standard key up event, there are so many events for this
and you to the difficult route?


Cor
 
M

Morten Wennevik [C# MVP]

Hi Joe,

ValueChanged is fired when the Value property is changed, and any Text
changed at this point would get overwritten by the Control at a later stage.

You can, however, achieve the padding by overriding OnTextBoxChanged

protected override void OnTextBoxTextChanged(object source, EventArgs e)
{
Text = Value.ToString("00");
}

but you will lose the ability to manually enter the value.

If you change to Text = Text.PadLeft(2, '0'); you can manually enter a
value, but you are no longer limited to maxvalue, and the user input is not
logical, but you may be able to work something out.
 
J

Joe Cool

Hi Joe,

ValueChanged is fired when the Value property is changed, and any Text
changed at this point would get overwritten by the Control at a later stage.

You can, however, achieve the padding by overriding OnTextBoxChanged

protected override void OnTextBoxTextChanged(object source, EventArgs e)
{
Text = Value.ToString("00");
}

but you will lose the ability to manually enter the value.

That is fine with me.
If you change to Text = Text.PadLeft(2, '0'); you can manually enter a
value, but you are no longer limited to maxvalue, and the user input is not
logical, but you may be able to work something out.

Thanks for your informative reply.
 
J

Joe Cool

Hi Joe,

ValueChanged is fired when the Value property is changed, and any Text
changed at this point would get overwritten by the Control at a later stage.

You can, however, achieve the padding by overriding OnTextBoxChanged

protected override void OnTextBoxTextChanged(object source, EventArgs e)
{
Text = Value.ToString("00");

No go. This statement throws a StackOverflowException.
 
P

Peter Duniho

[...]
You can, however, achieve the padding by overriding OnTextBoxChanged

protected override void OnTextBoxTextChanged(object source, EventArgse)
{
Text = Value.ToString("00");

No go. This statement throws a StackOverflowException.

I'm not a big fan of any of the suggestions. At some point, it seems like
it'd be better to just reimplement the control as a composite control,
handling the connection between the value and the displayed text
yourself. Just put a TextBox and a couple of buttons together yourself.

However, in the spirit of the hacking, I'll suggest that the above
technique _might_ work if you protect the assignment with a flag that
tracks whether you're actually trying to set the text. That is, the stack
overflow happens because you've got unterminated recursion, since the
method that handles a change in the text itself causes a change in the
text, causing the method to be called again.

So set a flag when you're changing the text and don't change it again if
you're already changing it:

bool _fChangingText;

protected override void OnTextBoxTextChanged(object source, EventArgs
e)
{
base.OnTextBoxTextChanged(source, e);

if (!_fChangingText)
{
_fChangingText = true;
Text = Value.ToString("00");
_fChangingText = false;
}
}

The reason I say "_might_" is that I don't know off the top of my head
what kinds of things the control does when you set the Text property. I
think it should work, but if the control starts doing something with the
text to parse or otherwise evaluate and reformat it, it could just wind up
overwriting whatever you put in there.

Pete
 
J

Joe Cool

[...]
You can, however, achieve the padding by overriding OnTextBoxChanged

protected override void OnTextBoxTextChanged(object source, EventArgs e)
{
Text = Value.ToString("00");

No go. This statement throws a StackOverflowException.

I'm not a big fan of any of the suggestions. At some point, it seems like
it'd be better to just reimplement the control as a composite control,
handling the connection between the value and the displayed text
yourself. Just put a TextBox and a couple of buttons together yourself.

Are you saying to have three controls on the form, a TextBox and two
Buttons? Or are you saying to create a UserControl that inherits from
the TextBox control and add a couple of buttons to it?

I would prefer the latter as it makes for a contorl that is easily
used in other projects. I looked into this briefly and cannot seem to
get the buttons to appear. The UserControl Designer looks different
from a Form Designer, and I have used code in the Form Designer to
figure out how to dynamically add controls to a form. And I have used
a UserControl that inherits from the NumericUpDown that adds rollover
and rollunder functionality, but I am having problems adding other
controls, like a couple of buttons to a TextBox.

Can you point me to a resource that can help with this understanding?
I have already done a Google search and checked with CodeGuru and
CodeProject with no luck.
However, in the spirit of the hacking, I'll suggest that the above
technique _might_ work if you protect the assignment with a flag that
tracks whether you're actually trying to set the text. That is, the stack
overflow happens because you've got unterminated recursion, since the
method that handles a change in the text itself causes a change in the
text, causing the method to be called again.

So set a flag when you're changing the text and don't change it again if
you're already changing it:

bool _fChangingText;

protected override void OnTextBoxTextChanged(object source, EventArgs
e)
{
base.OnTextBoxTextChanged(source, e);

if (!_fChangingText)
{
_fChangingText = true;
Text = Value.ToString("00");
_fChangingText = false;
}
}

I tried this and it doesn't seem to work.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top