In my program, I have texboxes which I type the grade of a student. But I want to restrict the user to not digit a number in format like 010 or 020. Also, if the user digits 1 and change to another textbox it autommaticaly changes this digited number (1) to 1,0.
I tried this, but when it enters the second condition, it gives me an error.
private void txt3Bimestre_Validated(object sender, EventArgs e)
{
if (txt3Bimestre.Text[0].ToString().Equals("1") ||
txt3Bimestre.Text[0].ToString().Equals("2") ||
txt3Bimestre.Text[0].ToString().Equals("3") ||
txt3Bimestre.Text[0].ToString().Equals("4") ||
txt3Bimestre.Text[0].ToString().Equals("5") ||
txt3Bimestre.Text[0].ToString().Equals("6") ||
txt3Bimestre.Text[0].ToString().Equals("7") ||
txt3Bimestre.Text[0].ToString().Equals("8") ||
txt3Bimestre.Text[0].ToString().Equals("9"))
{
if (txt3Bimestre.Text[1].ToString().Equals(",") || txt3Bimestre.Text.Substring(0, 2) == "10")
{
}
}
else
{
MessageBox.Show("Formato Inválido", "Alertaa", MessageBoxButtons.OK, MessageBoxIcon.Error);
txt3Bimestre.Clear();
txt3Bimestre.Focus();
}
}
The problem here is that you're trying to force user to not input data as he/she wants on the textbox.
What I recommend u to to is to let user enter what he/she wants and, after leave the textbox or execute another event, test the data if it's the valid format or show the user an alert about his/her "mistake".
For example:
double value;
bool ok = double.TryParse(txt3Bimestre.Text, out value))
if (ok)
{
txt3Bimestre.Text = value.ToString("0.00");
}
else
{
MessageBox.Show("Formato Inválido", "Alerta", MessageBoxButtons.OK, MessageBoxIcon.Error);
txt3Bimestre.Clear();
txt3Bimestre.Focus();
}
If you have problems with , or . for decimals (culture related differences for decimals separator), look for CultureInfo.InvariantCulture.
Hope it helps.
Related
I'm checking the user ID in the text box. And it can not start with a letter or digit '0'. I can catch the wrong entry and send a message to the screen. But the wrong entry will be in the text box until I hit another key. And if this is an acceptable digit then the wrong entry stays at the beginning of the string. So I need to get rid of the wrong entry immediately after the message dialog box. Any suggestion?
private void TxtUserID_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
{
MessageBox.Show(" Your User ID can not begin with a letter !!!");
//txtUserID.Text = string.Empty;
txtUserID.Clear();
}
else if (e.KeyChar == '0')
{
MessageBox.Show("Your User ID can not begin with 0 !!!");
txtUserID.Text = string.Empty;
}
}// end of keypress
I suggest using TextChanged instead of KeyPress event: whatever changed TxtUserID.Text (e.g. Paste, or, imagine, user put "12340" and then deleted "1234" in order to obtain "0") validate the TxtUserID
private static bool IsNameValid(string name) {
if (string.IsNullOrEmpty(name))
return true;
else if (name.Any(c => c < '0' || c > '9')) {
MessageBox.Show("Your User ID must contain digits only!");
return false;
}
else if (name.StartsWith("0")) {
MessageBox.Show("Your User ID must not start from 0!");
return false;
}
return true;
}
private void TxtUserID_TextChanged(object sender, EventArgs e) {
if (!IsNameValid(TxtUserID.Text))
txtUserID.Clear(); // Taken from the question
}
Edit: As Thomas Voß pointed out, clearing the entire text can be to cruel for a user (imagine that he's printed "1001234566978563" and then decided to remove leading "100"), probably
txtUserID.Text = string.Concat(txtUserID
.Text
.Where(c => c >= '0' && c <= '9') // Digits only
.SkipWhile(c => c == '0')); // Trim all starting '0'
instead of txtUserID.Clear(); when we remove all characters but digits and trim leadibng 0 is a better choice.
I have a simple form that takes 9 decimal numbers from 9 textboxes and I put some validation so that the users can only enter decimal numbers and nothing else.
Now the challenge I'm having is how to set the cursor in the textbox that had no decimal number after showing the error message in the try-catch statement?
Here's my code:
private void btn_Aceptar_Click(object sender, EventArgs e)
{
POI GPI = new POI();
POI VIM = new POI();
POI ST = new POI();
try
{
GPI.POI_x = Convert.ToDecimal(txt_GPIx.Text);
GPI.POI_y = Convert.ToDecimal(txt_GPIy.Text);
GPI.POI_z = Convert.ToDecimal(txt_GPIz.Text);
VIM.POI_x = Convert.ToDecimal(txt_VIMx.Text);
VIM.POI_y = Convert.ToDecimal(txt_VIMy.Text);
VIM.POI_z = Convert.ToDecimal(txt_VIMz.Text);
ST.POI_x = Convert.ToDecimal(txt_STx.Text);
ST.POI_y = Convert.ToDecimal(txt_STy.Text);
ST.POI_z = Convert.ToDecimal(txt_STz.Text);
}
catch (Exception)
{
MessageBox.Show("Ingrese solamente números en las variables GPI/VIM/ST", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Set the cursor in the first textbox that had no decimals..
return;
}
Comisurales Comisurales = new Comisurales();
Comisurales.calculo_coord_comisurales(PC, AC, IHP, GPI, VIM, ST);
}
Let me add that I also have a function to ensure the user is only limited to enter decimals but I wasn't able to figure how to avoid the "." only or this for example: "1."
As an addition to my question, here's what gets validated every time the user press a key in the textbox:
private void ValidarDecimal(object sender, KeyPressEventArgs e)
{
// permitir 0-9, backspace, y decimal
if (((e.KeyChar < 48 || e.KeyChar > 57) && e.KeyChar != 8 && e.KeyChar != 46))
{
e.Handled = true;
return;
}
// chequear solamente un decimal
if (e.KeyChar == 46)
{
if ((sender as TextBox).Text.IndexOf(e.KeyChar) != -1)
e.Handled = true;
}
}
I guess I have 2 ways to resolve my issue. Number one would be find a way to ensure the user never ever enters something weird in the textbox (which I've done partially) and number 2 would be to use the try-catch with the current limitations I mentioned above and then point the user to the textbox that has issues, both are acceptable.
The Decimal class has a TryParse method that could be used to avoid all this logic driven by catching exceptions (a very expensive approach in terms of performance)
decimal value;
if(decimal.TryParse(txt_GPIx.Text, out value))
GPI.POI_x = value;
else
{
MessageBox.Show("Invalid decimal value");
txt_GPIx.Focus();
}
Of course this code needs to be repeated for every control in your list, but you could write a generic function like this one
private decimal GetValueAndValidate(Textbox txt, out bool isOK)
{
isOK = true;
decimal value = 0m;
if(!decimal.TryParse(txt.Text, out value))
{
MessageBox.Show("Invalid decimal value");
txt.Focus();
isOK = false;
}
return value;
}
and then use the following approach in your code inside the button click
bool isOK = true;
if(isOK) GPI.POI_x = GetValueAndValidate(txt_GPIx, out isOK);
if(isOK) GPI.POI_y = GetValueAndValidate(txt_GPIy, out isOK);
.... and so on for the other fields ....
For the second part of your question, finding a way to completely control the input logic is not easy. What happens for example if your user PASTE an invalid text in your textbox? There are very edge case situations that takes a lot of effort to code correctly. It is a lot more easy to leave freedom of typing to your user and apply a strict logic when you get that input.
I am trying to get a messagebox to appear after a user closes my app. This messagebox lets the user know something based on their purchase. My problem is that my program crashes when it reads the "$" in the textbox. Here is where I'm currently at:
private void exitButton_Click(object sender, EventArgs e)
{
if
(MessageBox.Show("Are you sure you want to exit?",
"Confirm exit...",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
decimal Discount;
Discount = decimal.Parse(postDiscountCostTextBox.Text);
if (Discount <= 999.99m)
{
MessageBox.Show("This amount qualifies for 'A-100' frequent flier miles.",
"",
MessageBoxButtons.OK);
}
}
{
this.Close();
}
}
The program worked perfectly when I removed the "$" from the textbox, however, it needs to be there in the final product. Any help would be appreciated.
Use this instead:
Discount = decimal.Parse(postDiscountCostTextBox.Text.Replace("$", ""));
What if the current culture on the system has a symbol other than a dollar sign for currency?
The correct approach is to specify the "Currency" NumberStyles and use TryParse() instead of Parse():
decimal Discount;
if (decimal.TryParse(postDiscountCostTextBox.Text, System.Globalization.NumberStyles.Currency, null, out Discount))
{
if (Discount <= 999.99m)
{
MessageBox.Show("This amount qualifies for 'A-100' frequent flier miles.",
"",
MessageBoxButtons.OK);
}
}
else
{
// ... invalid value in textbox ...
// Dipslay a MessageBox?
}
I want to obligate the person who is using my program to enter only numbers in the text label in c#. How can i do that?
example :
number of equations : (he should only enter a number)
This code to obligate him to enter a number between 2 and 10 but i need a code for letters
if (int.Parse(txt1.Text) < 2 || int.Parse(txt1.Text) > 10)
{
l6.ForeColor = System.Drawing.Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
}
put this (or a variation of this, according to what you want to let the user to enter) in the textbox keypress event, so basically you will manage key presses in this textbox..
Add System.Media library to use the beep if the user enters wrong key, or remove it from the code...
if ((e.KeyChar >= '0') && (e.KeyChar <= '9') && (txt1.Text.Length < 10))
{
}
else if (e.KeyChar == 0x08)
{
//BACKSPACE CHAR
}
else if (txt1.SelectionLength > 0)
{
//IF TEXT SELECTED -> LET IT OVERRIDE
}
else
{
e.Handled = true;
SystemSounds.Beep.Play();
}
if (txt1.Text.Trim().Length > 0)
{
// Parse the value only once as it can be quite performance expensive.
Int32 value = Int32.Parse(txt1.Text)
if ((value >= 2) && (value <= 10))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
But, IMHO, TryParse is even better as it can handle bad string formats in a better way:
if (txt1.Text.Trim().Length > 0)
{
Int32 value;
if (!Int32.TryParse(txt1.Text, out value))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
What GUI do you use?
Using Winforms there are two ways that come to mind:
I recommend: Use a numericUpDown Control instead of a textBox. This way the user can only enter numbers and has nice Up/Down arrows to change the value. Plus you get handling of cursor keys.
Implement an Validating event handler.
Checking the various methods to insert text in a textbox to avoid non number chars is not an easy task and more often than not it fails somewhere. For example what about text pasted from the clipboard?, what about Backspace, Delete, Left, Right arrows keys?.
In my opinion it is better to follow a different approach.
Use the Validating event and let the user type or paste whatever he wants. At the validation event do you checks and advise the user or add a special errorProvider to signal the error:
private void l6_Validating(object sender, CancelEventArgs e)
{
int isNumber = 0;
if (l6.Text.Trim().Length > 0)
{
if (!int.TryParse(l6.Text, out isNumber))
{
e.Cancel = true;
errorProvider1.SetError(l6, "Svp choisir un nombre entre 2 et 10 ...";);
}
else
{
errorProvider1.SetError(l6, "");
}
}
}
}
Hello Fellow C# and Windows phone developers,
For my windows phone application, I have a textfield requiring the user to enter their age. During debugging mode I entered the number .8. and clicked proceed and the application unexpectedly closed. What code do I need to add so I can post a message box informing the user that numbers with more than 1 decimal point is unacceptable. Please Help
Assuming the input is a string, try:
if (input.IndexOf('.') == -1 || input.LastIndexOf('.') == input.IndexOf('.'))
{
//good
}
else
MessageBox.Show("More than one decimal point");
A better way though would be to use TryParse which will check the number for formatting
float age;
if (float.TryParse(input, out age))
{
//good
}
else
MessageBox.Show("Invalid age.");
one way would be to limit the number of decimal place input to just one decimal place when user is entering their input.
this would be much better as it is real time instead of checking it at the end.
private void tbx_KeyDown(object sender, KeyEventArgs e)
{
//mark the sneder as a textbox control so we can access its properties
TextBox textBoxControl = (TextBox)sender;
//if there is already a decimals, do not allow another
if (textBoxControl.Text.Contains(".") && e.PlatformKeyCode == 190)
{
e.Handled = true;
}
}