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.
You can use a simple text box and break the string as per this logic. I have only shown you for minutes and seconds you can extend it to hours following the code.
int seconds, minutes;
if (textBox1.Text.Length == 1 || textBox1.Text.Length == 2)
{
seconds = int.Parse(textBox1.Text);
}
else if (textBox1.Text.Length == 3)
{
seconds = int.Parse(textBox1.Text.Substring(1, 2));
minutes = int.Parse(textBox1.Text.Substring(0, 1));
}
else if (textbox1.Text.Length == 4)
{
seconds = int.Parse(textBox1.Text.Substring(2, 2));
minutes = int.Parse(textBox1.Text.Substring(0, 2));
}
Related
I am working on this method that validates a student Id number. The credentials of the ID number are; the first character has to be 9, the second character has to be a 0, there can not be any letters, and the number must be 9 characters long. The method will return true if the student id is valid. When I go to test the method manually through main it comes out as true, even when I put in a wrong input. In my code, I have the if statements nested, but I originally did not have them nested. What is a better way to validate the input to align with the credentials of the ID number? Would converting the string into an array be more ideal?
public static bool ValidateStudentId(string stdntId)
{
string compare = "123456789";
if (stdntId.StartsWith("8"))
{
if (stdntId.StartsWith("91"))
{
if (Regex.IsMatch(stdntId, #"^[a-zA-Z]+$"))
{
if (stdntId.Length > compare.Length)
{
if (stdntId.Length < compare.Length)
{
return false;
}
}
}
}
}
You can try regular expressions:
public static bool ValidateStudentId(string stdntId) => stdntId != null &&
Regex.IsMatch(stdntId, "^90[0-9]{7}$");
Pattern explained:
^ - anchor - string start
90 - digits 9 and 0
[0-9]{7} - exactly 7 digits (each in [0..9] range)
$ - anchor - string end
So we have 9 digits in total (90 prefix - 2 digits + 7 arbitrary digits), starting from 90
if i enter 10 digits first time it takes 10 digits but if i clear textbox1 using backspace and enter again it takes only 9 digits. it should take 10 digits because i have set textbox1.maxlength=9 means it should count 10 digits(0 to 9).
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar != '\b' && textBox1.Text.Trim().Length > 9)
{
e.Handled = true;
MessageBox.Show("You can't enter more than ten digits...");
textBox1.MaxLength = 9;
}
}
MaxLength is the literal amount of characters, i.e. a MaxLength of 9 has an index ranging from 0-8. Set MaxLength to 10.
MaxLength is used for counting the literal amount of characters within a string, therefore setting MaxLength to 9, would count 0-8, as 0 counts as a literal character.
Your solution would be to set MaxLength to 10.
What is the correct way to concatenate these elements?
Environment: C#-WinForm-Desktop.
In my app, I have a text file called config.ini. This file has values with this nomenclature:
csv_month_hour=value
The data are thus:
[csv]
csv_01_01=value // 24 hours a day in January
csv_01_02=value
csv_01_03=value
.
csv_02_01=value // 24 hours a day in February
csv_02_02=value
csv_02_03=value
.
// and so on
My app has this method called:
private void getMonthHour()
{
DateTime Xdt = DateTime.Now;
int Xmonth = Xdt.Month;
int Xhour = Xdt.Hour;
if (File.Exists("config.ini"))
{
IniFile ini = new IniFile("config.ini");
m3h = Convert.ToDouble(confg.csv["csv_" + Xmonth.ToString + "_" + Xhour.ToString]);
}
}
This method is called every seconds in timer_tick to check the month and time to use the corresponding value.
I need to know how to concatenate this:
m3h = Convert.ToDouble(confg.csv["csv_"+Xmonth.ToString+"_"+Xhour.ToString]);
An example of the code would be:
if (Xmonth==1&&Xhour==1){m3h = Convert.ToDouble(confg.csv.csv_01_01);}
else if (Xmonth==1&&Xhour==2){m3h = Convert.ToDouble(confg.csv.csv_01_02);}
else if (Xmonth==1&&Xhour==3){m3h = Convert.ToDouble(confg.csv.csv_01_03);}
// csv_month_hour in this case 01 is January.
else if (Xmonth==2&&Xhour==1){m3h = Convert.ToDouble(confg.csv.csv_02_01);}
// And so on, until December (12).
Putting aside the invalid syntax/compiler error from your method calls in your code, I suspect you're building the string but can't get the leading 0 in front of digits 0-9. So when Xmonth and Xhour are less than 10, your string is being built as "csv_1_1" instead of your intended "csv_01_01".
To instruct the ToString method to include a leading zero when needed, you can supply a custom numeric format string "00" (see the first entry in the link for "Zero placeholder").
Try using Xmonth.ToString("00") and Xhour.ToString("00"):
Monitor.malyt.m3h = Convert.ToDouble(confg.csv["csv_" +
Xmonth.ToString("00") + "_" +
Xhour.ToString("00")]);
This will output the values of Xmonth and Xhour with a single leading zero where needed.
I have a textbox and i want that it should have only 21 characters at max and they should be displayed in 3 lines(7 characters in each). As the user is typing when he types the 7th character i want the focus to be shifted to next line. I have already tried the following code
int textLength = a.Text.Length;
if (textLength % 8 == 0)
{
a.Text += "\n";
a.SelectionStart = a.Text.Length - 1;
}
It does not work .
Thanks for the help.
I have this code:
private void scrollLabel1_MouseDown(object sender, MouseEventArgs e)
{
for (int i = 0; i < ScrollLabel._lines.Length; i++)
{
}
}
_lines is type of string[]
_lines format is like this:
First index 0 contain some text: "hello"
Index 1 contain a line of date and time: Fri, 31 Jan 2014 18:31:12 +0200
Then index 2 is empty line space: ""
Then index 3 again a text: "hi"
Index 4 is again date and time: Fri, 31 Jan 2014 18:31:30 +0200
And os on there are 151 lines.
What i want to do is that when i click(down) on any line that is part of two lines text + date and time it will color this both lines.
For example i clicked on line in index 0 anywhere on this line it will color index 0 and index 1 if i clicked on line in index 2 that is empty do nothing.
If i click on line in index 3 or 4 then color lines 3 and 4.
If i clicked on line 3 or 4 color both lines 3 and 4.
If i clicked on line for example 123 or 124 color both 123 and 124.
How can i do it ?
ScrollLabel is a UserControl type Label i dragged to the form1 designer. And it dosent have index selected event or something like that.
If i is the index of the clicked line then do this:
int j = ((int)(i / 3)) * 3;
colorLine(j);
colorLine(j + 1);
// colorLine(j + 2); // not needed, that line is an empty string
The colorLine() method should take care of coloring the line of the given index. It should do something like this:
private void colorLine(int j)
{
ScrollLabel._lines[j] // put here code to color the line
}
How to actually color the line totally depends on what a line actually is. press . (dot) behind an instance to open Intellisense and see which methods and properties are available. One will allow coloring the line. If not, coloring is impossible and the whole attempt is impossible.