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;
Related
I have probably been overthinking it but I am trying to take a list I have and go through the list one by one with a keypress.
For example, I have three strings in a list, and when the player presses L it goes from option 1, to 2. Then 2 to 3. Then 3 to 1. I also need to save this option to a separate string.
Thanks to anyone who can help
Edit:
So I have one script that checks if they key has been pressed
private void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
gs.ChangeLevel(levelTxt);
}
}
And then on a different script I have the function that will change the option. I know this isn't correct but hopefully you will be able to see what i am trying to do
public List<String> levels;
public string level;
public void ChangeLevel()
{
level = levels.Count[]++;
if(levels.Count > levels.Count)
{
levels.Count[0];
}
}
Edit #2
So I have almost got it with help from the comments. I just need it to increment now (if this is suppose to it will only stay on the first one)
```
public string IncrementLevel()
{
if (levels.Count == 0)
{
levelIndex = 0;
return "";
}
levelIndex = (levelIndex >= levels.Count - 1) ? 0 : levelIndex++;
return levels[levelIndex];
}
And
public void ChangeLevel(Text level)
{
level.text = levels[levelIndex].ToString();
Debug.Log("It is now set to " + levels[levelIndex]);
}
Edit #3
Hey again guys, so the code shared in the comments helped but now I need to take it and decrease it with a different button. Any help would be appreciated.
I am not sure if we are on the same wavelength, however, if you just want to iterate a list then you need a pointer. You can create a function to increment the pointer and pop the value all in one.
private List<string> levels = new List<string>();
private int levelIndex = -1;
public string IncrementLevel()
{
levelIndex = (levels.Count == 0) ? -1 : (levelIndex >= levels.Count - 1) ? 0 : levelIndex + 1;
return (levelIndex == -1) ? "" : levels[levelIndex];
}
public string DecrementLevel()
{
levelIndex = (levels.Count == 0) ? -1 (levelIndex <= 0) ? levels.Count - 1 levelIndex - 1;
return (levelIndex == -1) ? "" : levels[levelIndex];
}
and
private void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
gs.ChangeLevel(IncrementLevel());
}
}
Try this:
// not tested for compilation, I used 0 as the start
// since that's the index of the first item in a list
int index = 0;
if (Input.GetKey("L"))
{
index++;
if (index > 2)
{
index = 0;
}
// the item you want is yourList[index],
// do whatever you want with it, just make sure
// it's used after the if index > 2 statement;
}
E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that's the first non-consecutive number.
If the whole array is consecutive then return null .
The array will always have at least 2 elements 1 and all elements will be numbers. The numbers will also all be unique and in ascending order. The numbers could be positive or negative and the first non-consecutive could be either too. please help me finish this code i am new in programming. My code:
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _2katas
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var input = this.txtInput.Text;
var numarray = input.Split(',');
int firstValue = Convert.ToInt32(numarray[0]);
for (var i = 0; i < numarray.Length; i++)
{
if (Convert.ToInt32(numarray[i]) - i != firstValue)
{
lblPrint.Text = "";
}
else
{
lblPrint.Text = "";
}
if (this.rdbConsecutive.Checked == true)
{
lblKataRunning.Text = "Consecutive";
}
else if (this.rdbStripCleaning.Checked == true)
{
lblKataRunning.Text = "Strip Cleaning";
}
}
}
}
}
Let's extract a method:
Find the first element of an array that is not consecutive ...
If the whole array is consecutive then return null
We can implement it like this:
private static string FirstInconsecutive(string data) {
var array = data.Split(',');
if (array.Length <= 0)
return null; //TODO: what shall we return on empty array?
if (!int.TryParse(array[0], out int delta))
return array[0];
for (int i = 1; i < array.Length; ++i)
if (!int.TryParse(array[i], out int value) || value - i != delta)
return array[i];
return null;
}
Usage:
string result = FirstInconsecutive(txtInput.Text);
Please note int.TryParse which helps to return the right answer "ABC" on an input like "1, 2, 3, ABC, 4, 6, 7, 8" (user input txtInput.Text can contain any string)
A linq solution just for the fun of it:
static int? FindFirstNonConsecutive(IEnumerable<int> arr)
{
var nonConsecutiveInfo =
arr.Select((i, index) => new {Index = index, Delta = i - index})
.FirstOrDefault(t => t.Delta != arr.First());
return nonConsecutiveInfo?.Delta + nonConsecutiveInfo?.Index;
}
Note that this will only work finding non consecutive numbers in ascending order as per requirements.
Two numbers are not consecutive if the left ones + 1 <> the right one.
Check with something like this, note that you have to change your boundary checks:
for (var i = 0; i < numarray.Length - 1; i++)
{
if (Convert.ToInt32(numarray[i]) + 1 != Convert.ToInt32(numarray[i+1]))
Update your condition as below for loop and it will work. I would suggest you to have separate function so that it could be reusable if needed elsewhere in code.
Here start your loop from i = 1 and compare numarray[i-1] + 1 != numarray[i] values.
You can convert your sting[] to int[] with var numarray = input.Split(',').Select(x => Convert.ToInt32(x)).ToArray(); and use it with IsConsecutive(numarray) as per button1_Click code.
You can get first non-consecutive value with minor modification in return type and return statement as shown in GetFirstNonConsecutiveValue().
public bool IsConsecutive(int[] numarray)
{
for (int i = 1; i < numarray.Length; i++)
{
if (numarray[i-1] + 1 != numarray[i])
{
return false;
}
}
return true;
}
public int? GetFirstNonConsecutiveValue(int[] numarray)
{
for (int i = 1; i < numarray.Length; i++)
{
if (numarray[i-1] + 1 != numarray[i])
{
return numarray[i];
}
}
return null;
}
private void button1_Click(object sender, EventArgs e)
{
var input = this.txtInput.Text;
var numarray = input.Split(',').Select(x => Convert.ToInt32(x)).ToArray();
var nonConsecutiveValue = GetFirstNonConsecutiveValue(numarray);
if (nonConsecutiveValue != null)
{
// nonConsecutiveValue is first non consecutive value.
}
else
{
// sequence is consecutive.
}
}
One way to go.
string rawData = "1,2,3,4,6,7,8,9";
IEnumerable<int> data = rawData.Split(',').Select(v => Convert.ToInt32(v));
IEnumerable<int> all = Enumerable.Range(data.Min(), data.Max() - data.Min() + 1);
IEnumerable<int> diff = all.Except(data);
if (diff.Count() == 0)
{
return null;
}
return data.ElementAt(all.ToList().IndexOf(diff.First()))
NB Not thoroughly tested.
Just test diff for being empty to get the numbers are consecutive
// 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 have tried the comparison for two integer values by using two types
Type 1 :
int val1 = 1;
int val2 = 2;
var returnValue = val1.CompareTo(val2);//-1 for First int is smaller.
varreturnValue = val2.CompareTo(val1);// 1 for First int is larger
varreturnValue = val1.CompareTo(val1);//0 for Ints are equal.
If(varreturnValue ==1)
{
//Success
}
else
{
//Failure
}
Type 2:
int val1 = 1;
int val2 = 2;
if (val1 < val2)
{
//return -1 //Failure
}
else if (val2 < val1)
{
//return 2 //Success
}
else
{
// return 0 // Same
}
What is the difference these methods?
Which one(type) is better for standard coding .. ?
Any difference for performance in the types ?
When I take a peek at the internals of int's CompareTo() method (using ReSharper), I see this:
public int CompareTo(int value)
{
if (this < value)
return -1;
return this > value ? 1 : 0;
}
So it would appear, in the case of an int anyway, that the CompareTo() function is doing exactly what your second example does.
If we remove the ternary operator, it looks identical to your example:
public int CompareTo(int value)
{
if (this < value)
return -1;
if (this > value)
return -1;
return 0;
}
In my opinion, the CompareTo method is good in case you need to separate the logic that checks for equality and another logic that uses the result from the comparison. In your example, when you do your code like:
int val1 = 1;
int val2 = 2;
if (val1 < val2)
{
//return -1 //Failure
}
else if (val2 < val1)
{
//return 2 //Success
}
else
{
// return 0 // Same
}
You cannot return to another function the comparison result. Here is the code extracted from msdn:
enum Comparison {
LessThan=-1, Equal=0, GreaterThan=1};
public class ValueComparison
{
public static void Main()
{
int mainValue = 16325;
int zeroValue = 0;
int negativeValue = -1934;
int positiveValue = 903624;
int sameValue = 16325;
Console.WriteLine("Comparing {0} and {1}: {2} ({3}).",
mainValue, zeroValue,
mainValue.CompareTo(zeroValue),
(Comparison) mainValue.CompareTo(zeroValue));
}
}
In this case, the comparison result is represented as an enum and can be passed between functions.
Another case is you could even serialize the comparison result over the wire as a numeric value (-1,0,1) (return value of an ajax call, for example)
There may be not much thing to do with numeric comparison like this, but as noted by Patryk Ćwiek in his comment. CompareTo may be used via interface, which can be implemented by other datatypes including your custom ones.
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;
}
}