I use WinForms
masked textbox to input time in the format of hh:mm:ss
. My mask for this is 99:99:99
, and I use right-to-left
input mode.
The problem is, when I type 123
into it, I expect it to input 1:23
, but it does this instead: __:12:3_
(so the value is 12:3x
, and it replaces x with the next value that is typed).
What can I do to make it just push text to the left instead of copying the whole ss
block to mm
?
Edit: Here's a clarification:
My client needs to input time values in such a way that when he types:
12[Enter]
it is accepted as 12 seconds
123[Enter]
is 1 minute, 23 seconds
1234[Enter]
would be 12 minutes, 34 seconds
12345[Enter]
would be 1 hour, 23 minutes, 45 seconds, and so on...
The problem is that when 123
is typed into a masked textbox, it moves 12
to the minutes
field, instead of just the 1
, and only the 3
is left inside the seconds
field.
Edit 2: As anyone who has worked with the masked textbox knows, setting the TextAlign to Right doesn't work the way you'd expect it to, like in any normal text editor. Instead, it just places the whole mask on the right side of the control, but the values are still inserted the same way as when the TextAligh is Left.
This is why I tried using RightToLeft.
What you want seems to be near impossible. How will the maskedtextbox know if you mean 1 digit to or 2 digits to apply to the first field that you type, unless you type the colon to show the separation?
I think for what you seem to want aDateTimePicker
with a custom format of hh:mm:ss
would work better. The input automatically starts at the hours
field. The user can type 1 digit or 2 digits and then the colon and the input will automatically move to the next field. You also have the option of UpDown buttons that the user can click on to change the highlighted field.
By near impossible, I meant with native behavior. By creating a custom textbox that inherits from textbox you can do what you want:
public class TimeTextBox : TextBox
{
public TimeTextBox()
{
this.KeyPress += TimeTextBox_KeyPress;
}
public DateTime timeValue = new DateTime();
private void TimeTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
if(char.IsDigit(e.KeyChar))
{
Text += e.KeyChar;
SelectionStart = Text.Length;
}
else
{
MessageBox.Show("Wrong input");
return;
}
FixText();
if(Text.Length > 3 && !DateTime.TryParse(Text, out timeValue))
{
MessageBox.Show("Wrong input");
Text = Text.Remove(Text.Length - 1);
FixText();
timeValue = DateTime.Parse(Text);
}
}
private void FixText()
{
Text = Text.Replace(":", "");
for(int i = Text.Length - 3; i > -1; i -= 2)
{
Text = Text.Insert(i + 1, ":");
SelectionStart = Text.Length;
}
}
}
This will format and validate the input always counting from the right and inserting colons every 2 characters. There's simple validation, but it hasn't been tested for all scenarios.