I feel kind of silly asking this because either I'm missing something increidbly easy or not understanding the tryParse function at all.
In laymans terms, what I want to do in the following code is have the code loop through all of the columns in a datagridview. If the last 2 characters of the column name are numeric, I then want to compare the numeric value of the last 2 characters (using int.TryParse) to another variable. essentially I want to make all of my columns read only excpet for those columns where the last 2 digits can be converted to an integer and that integer is greater than the vairable I'm comparing to.
My code below is probably a little mundane as I'm trying to go through step by step setting variables before the int_tryParse but I can fix that later.
C#, VS2008:
foreach (DataGridViewColumn col in grd1.Columns)
{
string myCol = col.Name;
int myColLength = col.Name.Length;
string myColMonth = myCol.Substring(myColLength - 2);
if (int.TryParse(myColMonth, out myColMonth) <= myMostRecentActualMonth)
{
col.ReadOnly = true;
}
else
{
col.ReadOnly = false;
}
}
The TryParse method returns a Boolean value indicating if the parse was successful or not. If so, it sets the output parameter to the parsed value.
So what you'll want is something like:
int parsedMonth; // This will get set if myColMonth is a valid integer
if (int.TryParse(myColMonth, out parsedMonth) && parsedMonth <= myMostRecentActualMonth)
{
// ...
}
int.TryParse has a return type of bool:
Try going from here:
foreach (DataGridViewColumn col in grd1.Columns)
{
string myCol = col.Name;
int myColLength = col.Name.Length;
string myColMonth = myCol.Substring(myColLength - 2);
int myIntColMonth;
if (int.TryParse(myColMonth, out myIntColMonth)
&& myIntColMonth <= myMostRecentActualMonth)
{
col.ReadOnly = true;
}
else
{
col.ReadOnly = false;
}
}
TryParse returns a bool indicating whether or not the conversion was successful. You don't want to compare the result of TryParse (what you're doing) you instead want to compare with the variable you're passing into it.
So;
if (int.TryParse(myColMonth, out myColMonth) <= myMostRecentActualMonth)
needs to become;
if (int.TryParse(myColMonth, out myColMonth)
if ( myColMonth <= myMostRecentActualMonth)
First checking that you parsed out an int, then doing the compare.
foreach (DataGridViewColumn col in grd1.Columns)
{
string myCol = col.Name;
int myColLength = col.Name.Length;
string myColMonth = myCol.Substring(myColLength - 2);
int myColMonthInt = 0;
if (int.TryParse(myColMonth, out myColMonthInt))
{
if (myColMonthInt <= myMostRecentActualMonth)
{
col.ReadOnly = true;
}
else
{
col.ReadOnly = false;
}
}
else
{
// what do you want to do is last two chars can't be converted to int?
col.ReadOnly = true;
}
}
You could rewrite your code like this, first you need another int value to which you should store your parsed value, then check if that value is lower than myMostRecentActualMonth
foreach (DataGridViewColumn col in grd1.Columns)
{
string myCol = col.Name;
int myColLength = col.Name.Length;
string myColMonth = myCol.Substring(myColLength - 2);
int myColMonthIntValue = int.MaxValue;
if (int.TryParse(myColMonth, out myColMonthIntValue) && myColMonthIntValue <= myMostRecentActualMonth)
{
col.ReadOnly = true;
}
else
{
col.ReadOnly = false;
}
}
Related
I want to check datatype of entered text in c#
What I have done
if (!row.IsNull(dt.FieldCaption))
{
string value = row[dt.FieldCaption].ToString();
if(!string.IsNullOrEmpty(value))
{
switch (dt.DataType.ToLower())
{
case "int":
int v = 0;
int.TryParse(value, out v);
return true;
default:
return false;
}
}
}
I'm unable to return the value.
Thanks in advance
Probably you are talking about the DataTable.
To get the cell values you can do something like that:
for(int i = 0; i< dt.Rows.Count;i++)
for (int j = 0; j <dt.Columns.Count ; j++)
{
object o = dt.Rows[i].ItemArray[j];
//if you want to get the string
//string s = o = dt.Rows[i].ItemArray[j].ToString();
}
Than you should know what kind of types are suppose to be stored in the your cells.
Or you can implement a function to convert string to a type:
int toReturnInt;
if (int.TryParse(s, out toReturn))
{
return toReturnInt
}
bool toReturnBool;
if (bool.TryParse(s, out toReturnBool))
{
return toReturnBool
}
"Datatype" of cell values
if (!row.IsNull(dt.FieldCaption))
{
string value = row[dt.FieldCaption].ToString();
if(!string.IsNullOrEmpty(value))
{
bool toReturnBool;
bool toReturnInt;
if (int.TryParse(value, out toReturnInt))
{
// Datatype int
return toReturnInt;
}
else if (bool.TryParse(value, out toReturnBool))
{
// Datatype bool
return toReturnBool;
}
else
{
// assume that it's string.
return value;
}
}
}
I assume you are trying to read the Excel sheet using OLEDB. If that is the case, your code seems to be returning correctly the value after the call to
dt.DataType.ToLower()
in your switch statement. However, it looks like you are checking for the wrong value in your case statement. Instead of "int", you should be checking for one of the values of the OleDbType (https://learn.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbtype?view=netframework-4.7.2) enum.
I would try something similar to the following code (even if the return part seems strange to me, probably you have to handle the result of this code differently from what you are currently doing):
switch (dt.DataType)
{
case OleDbType.Integer:
int v = 0;
int.TryParse(value, out v);
return true;
default:
return false;
}
I have a methode who add numbers together parsed from a string.
If user type : "52+7+1", it will result in (60)
"52++2+3", "52+c+2", "+52+2", "52+2++", ... won't work.
My code works almost perfectly, expect... it ignores the last character. It works when, in the code I add "+0" to the string but of course it brokes the condition who prevent the user to type "+" as a last character.
public int addFromString(string str)
{
bool valid_str = true;
bool current_char_numeric = false;
string unparsedNumber = "";
int parsedNumber = 0;
List<int> parsedNumbers = new List<int>();
if (string.IsNullOrEmpty(chaine))
chaine_valide = false;
else
{
if (!int.TryParse(str[0].ToString(), out parsedNumber))
valid_str = false;
if (!int.TryParse(str[str.Length - 1].ToString(), out parsedNumber))
valid_str = false;
}
foreach (char c in str)
{
current_char_numeric = int.TryParse(c.ToString(), out parsedNumber);
if (current_char_numeric)
unparsedNumber += c;
else if(c == '+')
{
int.TryParse(unparsedNumber, out parsedNumber);
parsedNumbers.Add(parsedNumber);
if (str.IndexOf(c) < str.Length && str.ElementAt(str.IndexOf(c) + 1) == '+')
valid_str = false;
//Just in case :
unparsedNumber = "";
current_char_numeric = int.TryParse(c.ToString(), out parsedNumber);
}
else valid_str = false;
}
int result = 0;
if(valid_str) { foreach(int n in parsedNumbers) { result += n; } }
return result;
}
So if I type : "52+2" I get 52
If I type : "52+2+6" I get 54
It misses the last value because you only add numbers if you find a +. So for the last unparsedNumber you never enter the else if (c == '+') block.
Let me suggest an more compact solution:
public int addFromString(string str)
{
string trimmed = str.Trim();
if (str.StartsWith("+") || str.EndsWith("+")) return 0; // invalid -> return immediatly
// split string at "+" and trim parts
string[] numbers = str.Split('+').Select(s => s.Trim()).ToArray();
int result = 0;
foreach(string number in numbers)
{
int n;
if (!int.TryParse(number, out n)) return 0; // invalid -> return
result += n;
}
return result;
}
You only add a number to the numbers collection when you encounter a +.
What about the last number? There's no '+' after that.
You should add unparsedNumber to parsedNumbers for the last number too.
You can do a more elegant version:
public int addFromString(string str)
{
int parsedNumber = 0;
int result = 0;
if (string.IsNullOrEmpty(chaine))
{
return result;
}
else
{
if (!int.TryParse(str[0].ToString(), out parsedNumber)
|| !int.TryParse(str[str.Length - 1].ToString(), out parsedNumber))
{
return result;
}
}
try
{
result = str.Split(new char[] { '+' }).Select(s => Convert.ToInt32(s)).Sum();
}
finally
{
return result;
}
}
It seems that all you want is Split:
string source = "52+7+1";
int sum = 0; // initial sum is 0
bool chaine_valide = true; // the chain is valid (we don't have any counter examples)
// Split on terms: 52, 7, 1
foreach (string term in source.Split('+')) {
int value;
// No need in Trim() etc. - TryParse is smart enough
if (int.TryParse(term, out value))
sum += value; // valid term: add it up
else {
chaine_valide = false; // counter example: term is not a valid integer
break;
}
}
...
Console.Write(chaine_valide ? sum.ToString() : "Invalid formula");
In case of C# 7.0 you can (with a help of out var) simplify the code into
int sum = 0; // initial sum is 0
bool chaine_valide = true; // the chain is valid (we don't have any counter examples)
// Split on terms: 52, 7, 1
foreach (string term in source.Split('+'))
if (int.TryParse(term, out var value))
sum += value; // valid term: add it up
else {
chaine_valide = false; // counter example: term is not a valid integer
break;
}
// if user input is negative
if (h < 0)
{
// assign absolute version of user input
number = Math.Abs(n);
pictureBox14.Visible = true;
}
else
{
// else assign user input
number = n;
number = 0; // if user input is not an int then set number to 0
pictureBox6.Visible = true;
}
What is the correct code for validating to int ONLY? That integer is the only one I want to input in the textbox then the picturebox will appear.
Use int.TryParse method
int value= 0;
if (int.TryParse(n, out value))
{
if (value< 0)
number = Math.Abs(value);
else
number = value;
}
There is no need for a complicated if statement. You can do it like this.
int number = 0;
bool isValid = int.TryParse(userInputString, out number);
number = Math.Abs(number);
if (isValid)
{
pictureBox14.Visible = true;
}
You first want to parse user Input, then validate the range:
int ExampleFunc( string userInput )
{
int nVal;
if( int.TryParse( userInput, out nVal ) )
{
return Math.Abs( nVal );
}
else return 0;
}
There's no reason to check if the number is negative, just always use the absolute value. Convert will return a 0 value if the string passed to it from the text input cannot be converted properly, so this code handles your question in just one line. If you want the picture box to show based on the int value, test that after the conversion.
int number = Math.Abs(Convert.ToInt32(textInput));
I am working with a datagrid view, this datagrid view allows the user to edit cells, I want to set it up so that when a user inserts a negative value, it will convert this value to 0, what would be the best way to code this, i have created the followin code below, it appears to check for negative values, however it does not change the value to zero
if (Convert.ToInt32(dgvDetails.CurrentRow.Cells[2].Value.ToString()) < -0)
{
intQtyInsp = 0;
}
else
{
intQtyInsp = Int32.Parse(row.Cells[2].Value.ToString());
That might be because dgvDetails.CurrentRow.Cells[2].Value.ToString() and row.Cells[2].Value.ToString() might not be the same cell you are checking..
This will do what you require
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCell currentCell =
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
int cellValue = Convert.ToInt32(currentCell.Value);
if (cellValue < 0)
currentCell.Value = 0.ToString();
}
I hope this helps.
intQtyInsp =Int32.Parse(dgvDetails.CurrentRow.Cells[2].Value.ToString());
if(intQtyInsp < 0)
{
intQtyInsp = 0;
}
if(score < 0) { *score = 0; }
int valueFromCell = Convert.ToInt32(dgvDetails.CurrentRow.Cells[2].Value.ToString());
intQtyInsp = valueFromCell < 0
? 0
: valueFromCell ;
I suggest to use a extension method to ensure if the user inputs a int.
Extension method
public static class StringExtension
{
public static int TryConvertToInt32(this string value)
{
int result = 0;
if (Int32.TryParse(value, out result))
return result;
return result;
}
}
Usage
// call the extension method
int intQtyInsp = dgvDetails.CurrentRow.Cells[2].Value.ToString().TryConvertToInt32();
// And check for lower than zero values.
intQtyInsp = intQtyInsp >= 0 ? intQtyInsp : 0;
List<string> arguments = new List<string>(Environment.GetCommandLineArgs().Skip(1).Take(4));
int variant = consoleOptions.HandleInput(arguments);
public int HandleInput(List<string> input)
{
int variant = 0;
//for (int i = 0; i < input.Count; i++)
//{
// if (input[i].Contains("-s"))
// {
// variant = 1;
// }
//}
if (input[0].Contains("-s"))
{
variant = 1;
if (!String.IsNullOrWhiteSpace(input[1]) && !String.IsNullOrWhiteSpace(input[2]))
{
variant = 2;
}
if (!String.IsNullOrWhiteSpace(input[3]))
{
variant = 3;
}
}
return variant;
}
I'm starting my application from Commandline.
Then I get a List of Strings (max 4).
What I want to do now is:
if the first String in List is "-s" then variant = 1
if the second and third string isn't Empty then variant = 2
if the fourth string isn't Empty then variant = 3
I tried some things (Code above), but the problem is, if I only get the first String (one item),
The Compiler crashes on other place (checking Second string, cause Index not accessible)..
What would be the best method?
The Take(4) doesn't guarantee that you'll have 4 elements, it just means you won't have more than 4. So you have to check the list length.
if (input.Count >= 1 && input[0].Contains("-s"))
{
return 1;
}
if (input.Count >= 3)
{
return 2;
}
if (input.Count >= 4)
{
return 3;
}
return 0; //what do you return if none of the conditions are met?
you try some thing like this.
if (input[0].Contains("-s"))
{
variant = 1;
}
if (!String.IsNullOrWhiteSpace(input[1]) && !String.IsNullOrWhiteSpace(input[2]))
{
variant = 2;
}
if (!String.IsNullOrWhiteSpace(input[3]))
{
variant = 3;
}
return variant;