I have a PreviewKeyDown event in my grid and i want to let just numeric value and (0,2) decimal value.
private void dgvUser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
colUser = dgvUser.CurrentCell.ColumnIndex;
rowUser = dgvUser.CurrentCell.RowIndex;
DataGridViewCell tc = dgvUser[colUser, rowUser];
valueUser = Convert.ToDouble(tc.Value);//code breaks here
if (e.KeyData == Keys.Enter && dgvUser.CurrentCell.ColumnIndex == 2 && handledUser == true)
{
DragerClass.Dedektör.Dedektor_A1Set[Convert.ToInt32(dgvUser.Rows[rowUser].Cells[0].Value) - 1] = valueUser;
BindUserGrid(userPagingUpdate[0], userPagingUpdate[1]);
logValues(Convert.ToInt32(dgvUser.Rows[rowUser].Cells[0].Value) - 1);
handledUser = false;
}
}
When i enter non numeric value code breaks in valueUser = Convert.ToDouble(tc.Value); line. how can i prevent that?
You can use Double.TryParse method:
if (Double.TryParse(tc.Value.ToString(), out valueUser))
{
//success
}
else
{
//fail
}
Either you can use a Try/Catch statement,
try
{
valueUser = Convert.ToDouble(tc.Value);
}
catch
{
// if the above line throws an exception deal with it here.
}
or you could use double.TryParse()
double valueUser;
bool isNumber = double.TryParse(tc.Value,out valueUser);
Another solution would be to set the DataGridViewCell.ValueType that you use as a template for your column to typeof(decimal) this will create a DataError Event every time the user tries to input a value different to what you have specified. You can then handle that DataError Event to whatever you like.
Related
I am trying to save the .text of a label to a database but sometimes that label is an infinity symbol. To catch for this I have created an if statement which checks if the label is a number or not and throws a message box up to tell the user. However more often than not the label will be a decimal number and the if statement throws up the message box. I was wondering if anyone could help me out please?
private void btnSaveResults_Click(object sender, EventArgs e)
{
btnClearData.Enabled = true;
if (System.Text.RegularExpressions.Regex.IsMatch(lblAerobicCap.Text, "[^0-9]"))
{
MessageBox.Show("Im sorry, there seems to have been an error in the inputting of the readings, please restart the test");
}
else
{
AthletesDetailsNew users = new AthletesDetailsNew();
DateTime dateTimeVariable = DateTime.Now;
users.Date_Of_Test = dateTimeVariable;
users.First_Name = comboBoxFirstName.Text;
users.Surname = comboBoxNewSurname.Text;
users.Age = int.Parse(comboBoxAge.Text);
users.Account_Number = int.Parse(comboBoxAccountNumber.Text);
users.Aerobic_Capacity = /*Math.Truncate*/(decimal.Parse(lblAerobicCap.Text));
DataClassDataContext dbCtx = new DataClassDataContext();
dbCtx.AthletesDetailsNews.InsertOnSubmit(users);
try
{
dbCtx.SubmitChanges();
MessageBox.Show("Data saved");
}
catch
{
MessageBox.Show("Data failed to save");
}
}
}
You should use the .TryParse() method for this.
for example:
decimal value;
bool isNumber = Decimal.TryParse(inputVariable, out value);
Use decimal.TryParse so in case of success you can reuse the result
decimal aerobicCap = -1;
if (!decimal.TryParse( lblAerobicCap.Text, out aerobicCap))
{
MessageBox.Show("Im sorry, there seems to have been an error in the inputting of the readings, please restart the test");
}
else
{
// code ...
users.Aerobic_Capacity = aerobicCap;
I think you need to trim the spaces from lblAerobicCap.Text prior to checking if the value is a number. Something like lblAerobicCap.Text = lblAerobicCap.Text.Trim().
lblAerobicCap.Text = lblAerobicCap.Text.Trim();
if (System.Text.RegularExpressions.Regex.IsMatch(lblAerobicCap.Text, "[^0-9]"))
{
MessageBox.Show("Im sorry, there seems to have been an error in the inputting of the readings, please restart the test");
}
[ ... ]
Better still avoid users entering anything but numbers. That way you do not have to validate the input.
For the digits use something like this:
void Control_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
Decimal:
void Control_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode != Keys.Decimal)
{
e.Handled = true;
}
}
I have used an extension method in the past which works nicely for me:
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
object testObject = 0.1;
if (testObject.IsNumber()) { MessageBox.Show("Hooray!"); }
I am trying to read Current value of Text Box in PreviewKeyDown Event but unable to get current value.
Here is my code ,
private void txtDoscountValue_PreviewKeyDown(object sender, KeyEventArgs e)
{
try
{
if (txtDoscountValue.Text == string.Empty)
discountPercentage = 0;
else
discountPercentage = float.Parse(txtDoscountValue.Text);
CalculateCart(cartItems, discountPercentage, 0);
}
catch
{ }
}
Maybe your problem is that you are asking at PreviewKeyDown, so when it gets called, there is still no values in the box. If you want to get called when the box actually changes you need to hook to KeyDown or even better TextChanged.
PreviewKeyDown is for checking the content of the change before actually applying it, which is kind of validation.
The value of the modification is stored in the keyEventArgs, not in the textbox.
It is possible to read value of TextBox at any time with Text property of TextBox control:
var currentValue=textBox.Text;
To read inputted keys of keyboard, you can use e.Key of KeyEventArgs:
private void txtDoscountValue_PreviewKeyDown(object sender, KeyEventArgs e)
{
try
{
string input=e.Key;
var ee = txtDoscountValue.Text;
}
catch { }
}
Update:
It is possible to use KeyConverter class to convert Keys to string. You should add reference to assembly System.Windows.Forms to your WPF project to use KeyConverter class:
private void textBox1_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
try
{
char c = '\0';
System.Windows.Input.Key key = e.Key;
if ((key >= Key.A) && (key <= Key.Z))
{
c = (char)((int)'a' + (int)(key - Key.A));
}
else if ((key >= Key.D0) && (key <= Key.D9))
{
c = (char)((int)'0' + (int)(key - Key.D0));
}
else if ((key >= Key.NumPad0) && (key <= Key.NumPad9))
{
c = (char)((int)'0' + (int)(key - Key.NumPad0));
}
//here your logic
}
catch { }
}
}
I want to make a TextBox which does not allow to enter a value above 100. Only numbers allowed, And a Numeric TextBox is not an option. This is my code for now:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)) { e.Handled = true; } // only numbers
}
Any ideas?
You should use int.TryParse to see if the parsing is successful and then compare the value to see if it is below 100.
int number;
if(int.TryParse(textBox1.Text, out number))
{
if(number <= 100)
{
//in range
}
else
{
// not in range
}
}
else
{
//invalid number
}
You can also use double.TryParse or other TryParse method depending on the type, they are safe to use, since they will return a false if the parsing fails, instead of raising an exception.
Hello, here is my solution.
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
char c = e.KeyChar;
if ((!char.IsDigit(c) ||
Convert.ToInt32(textBox.Text + e.KeyChar) >= 101 ||
textBox.Text == "0") && c != '\b')
e.Handled = true;
}
Finally. I found a solution:
int box_int = 0; Int32.TryParse(textBox1.Text, out box_int);
if (box_int > 1050 && textBox1.Text != "") { textBox1.Text = "1050"; }
You can enter only numbers and use arrows keys and backspace. If you enter a number > than 100 or less than 1, when you press enter it will be cancelled. Copy and Past with button key down is disabled and also mouse right click to prevent the user to paste in the text box is disabled/handled. This should solve your problem in full.
First of all set:
ShortcutsEnabled property of your text box to False
this will not allow mouse right click and ctrl+V for paste in your text box.
Then add the following code:
//prevent letters, special chars, punctuation, symbols, white spaces
private void txtType1_KeyPress(object sender, KeyPressEventArgs e)
{
{
if (char.IsLetter(e.KeyChar) ||
char.IsSymbol(e.KeyChar) ||
char.IsWhiteSpace(e.KeyChar) ||
char.IsPunctuation(e.KeyChar))
e.Handled = true;
}
{
//allows only numbers between 1 and 100
string value = txtType1.Text;
if (txtType1.Text !="")
{
if (Int16.Parse(value) < 1 )
{
txtType1.Text = "";
}
else if (Int16.Parse(value) > 100)
{
txtType1.Text = "";
}
}
}
}
In my datagridview, four columns 1 & 2 are read only col 3 & 4 got number values. I want to compare that 4th column must be greater that 3rd column.
For example:
If the 4th column value is less than the 3rd column then I want to propose message doesn't navigate to another control.
My simple approach seems not working. How can I compare 2 specific columns for this kind of condition?
private void datagridview_CellValidating(object sender, CellValidatingEventArgs e)
{
try
{
int bbor = datagridview.CurrentCell.ColumnIndex;
int ebor = datagridview.CurrentCell.RowIndex;
if (ebor <= bbor)
{
MessageBox.Show("Please verify the value");
e.Cancel = true;
}
}
catch (Exception exception)
{
}
}
we meet again. Use the cell_click event:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex != 0)
{
if (Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()) <= Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
{
MessageBox.Show("Please verify the value");
}
}
}
EDIT 1: This seems to work fine, lemme know.
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex != 0)
{
if (Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()) <= Double.Parse(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
{
MessageBox.Show("Please verify the value");
e.Cancel = true;
}
}
}
Edit 2: Updated for Telerik controls
private void radGridView1_CellValidating(object sender, Telerik.WinControls.UI.CellValidatingEventArgs e)
{
if (e.ColumnIndex != 0)
{
if (e.Value != null && radGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value != null)
{
if (Double.Parse(e.Value.ToString()) <= Double.Parse(radGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex - 1].Value.ToString()))
{
MessageBox.Show("error");
e.Cancel = true;
}
}
}
}
I'd see something more or less like that:
If you want to check all rows:
DataRow dr;
for(int i = datagridview.Rows.Count-1; i > 0; i--) {
dr = datagridview.Rows[i];
if(dr[e.ColumnIndex] > dr[e.ColumnIndex+1]){
//your message code
e.Cancel = true;
break; (or return;)
}
}
If you want to check only the current row where the cell is being edited:
DataRow dr = datagridview.Rows[e.RowIndex];
e.Cancel = dr[e.ColumnIndex] > dr[e.ColumnIndex+1];
if(e.Cancel)
//your message code
Maybe you will need to convert objects to int for comparison.
See the Rows Property for DataGridView http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rows.aspx
this.dataGridView1[col, row].Value
references a specific cell for each row
foreach (Row r in this.dataGridView1.Rows) {
if (r.Cells[3].Value <= r.Cells[2].Value ) {
System.Console.WriteLine ("error");
}
}
For your validation check you'll want to use the FormattedValue property to see what value your user wants to insert in the cell they've edited. You can't use the current cell value because it doesn't update to the new value until after the CellValidating completes without DataGridViewCellValidatingEventArgs.Cancel being set to true.
Something like this:
private void datagridview_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
// This is the new proposed value the user entered; could be for column 3 or 4.
int newValue = int.Parse(e.FormattedValue.ToString());
// See which column fired the CellValidating event and use the new proposed value for it
// in place of the cell's actual value for purposes of our validation.
int col3Value = (e.ColumnIndex == 2) ? newValue : (int)dataGridView1[2, e.RowIndex].Value;
int col4Value = (e.ColumnIndex == 3) ? newValue : (int)dataGridView1[3, e.RowIndex].Value;
if (col3Value <= col4Value) {
MessageBox.Show("Please verify the value");
e.Cancel = true;
}
}
The code I show here is to demonstrate a solution to your problem. In your actual production code
you'll want to verify that casting from object to int is successful (through int.TryParse) or catch the exception that's raised when this operation fails. When this happens you can Cancel = true the cell validation and present to the user a message that he must enter a number.
And another quick note: don't use empty catch blocks (though I realize this probably isn't in your production code).
if (textBox1.Text != "") // this forces user to enter something
{
// next line is supposed to allow only 0-9 to be entered but should block all...
// ...characters and should block a backspace and a decimal point from being entered....
// ...but it is also allowing characters to be typed in textBox1
if(!IsNumberInRange(KeyCode,48,57) && KeyCode!=8 && KeyCode!=46) // 46 is a "."
{
e.Handled=true;
}
else
{
e.Handled=false;
}
if (KeyCode == 13) // enter key
{
TBI1 = System.Convert.ToInt32(var1); // converts to an int
Console.WriteLine("TBI1 (var1 INT)= {0}", var1);
Console.WriteLine("TBI1= {0}", TBI1);
}
if (KeyCode == 46)
{
MessageBox.Show("Only digits...no dots please!");
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
}
else
{
Console.WriteLine("Cannot be empty!");
}
// If I remove the outer if statement and skip checking for an empty string, then
// it prevents letters from being entered in the textbox. I need to do both, prevent an
// empty textbox AND prevent letters from being entered.
// thanks, Sonny5
You didn't specify where this code runs, but my assumption would be it runs on key down. Since key down is received before the character is processed and the Text property is updated, your check for .Text == "" will prevent the rest of the validation running, at least for the first character.
You should move the check for empty value on a different event than the check for the key pressed.
I think you could use the IsDigit function.
Something along these lines:
string textBoxText = "12kj3";
if (!textBoxText.Equals(String.Empty)) // this forces user to enter something
{
foreach (char c in textBoxText.ToArray())
{
if (!Char.IsDigit(c))
{
//return false;
}
}
//return true;
}
else
{
Console.WriteLine("Cannot be empty!");
}
Hope you get the idea.
You can use the following RegEx to check that it is a number "^\d+$" and required.
bool bV=false;
private void textBox1_Validated(object sender, EventArgs e)
{
TextBox textBoxText = sender as TextBox;
if (!textBoxText.Equals(String.Empty))
{
foreach (char c in textBoxText.Text.ToArray())
{
if (!Char.IsDigit(c))
{
if (!bV)
{
MessageBox.Show("Input value not valid plase Insert Integer Value");
bV = true;
textBox1.Text = String.Empty;
break;
}
}
}
}
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
bV = false;
}