Index out of range in C# - c#

I tried to debug this code, but I cannt how to fix it.
If I use this code, my WF run:
try
{
rtxttdwhat.Text = dataGridView1.CurrentRow.Cells[8].Value.ToString();
lbtdtime1.Text = dataGridView1.CurrentRow.Cells[1].Value.ToString() +
":" + dataGridView1.CurrentRow.Cells[0].Value.ToString();
the other, it's show INDEX OUT OF RANGE:
int a, b;
a = 1;
b = a+1;
try
{
if (int.Parse(dataGridView1.Rows[a].Cells[1].Value.ToString()) == int.Parse(lbhour.Text) &&
int.Parse(dataGridView1.Rows[a].Cells[0].Value.ToString()) == int.Parse(lbmin.Text))
{
a = a + 1;
b = a + 1;
}
rtxttdwhat.Text = dataGridView1.Rows[a].Cells[8].Value.ToString();
lbtdtime1.Text = dataGridView1.Rows[a].Cells[1].Value.ToString() +
":" + dataGridView1.Rows[a].Cells[0].Value.ToString();

I am not 100% sure what are you doing, especially with b? But you could try this:
int RowCount = dataGridView1.Rows.Count;
if(a <= RowCount)
{
//Youre Code
}
else
{
//Out of Range
}

Hi This link may be useful for you
IndexOutOfRangeException
Modify your code and Check for Rows and Cells Counts first before accessing them.

Related

check numeric value of a datagrdiview cell value?

In my project, I have a datagridview with some columns, one of the columns have a numeric value. I want to perform a check for this cell value but it gives me an error
string was not in a correct value.
this is my code:
foreach (DataGridViewRow rw in dgv_student_update.Rows)
{
for (int i = 0; i < dgv_student_update.Rows.Count; i++)
{
if (Convert.ToInt32(rw.Cells[3].Value) == 4)
{
sc.archive_student(dgv_student_update.Rows[i].Cells[2].Value.ToString(),last_year + " - " + current_year,Convert.ToInt32(dgv_student_update.Rows[i].Cells[1].value));
}
}
}
can anyone help please?
Try this
Func<DataGridViewRow, int, int> cellValue = (row, i) => {
int.TryParse(row.Cells[i].Value + "", out i); return i; }; // returns 0 if TryParse fails
foreach (DataGridViewRow rw in dgv_student_update.Rows)
if (cellValue(rw, 3) == 4)
sc.archive_student(rw.Cells[2].Value.ToString(),
last_year + " - " + current_year, cellValue(rw, 1));
It's just a matter of proper null and value checking. You cannot assume everything has a value and it is in the format you expect. First make sure the cell has a value. Then make sure the value can be converted to an integer. Follow this advice for your update as well, you are likely to hit the same kind of problem calling archive_student.
for (int i = 0; i < dgv_student_update.Rows.Count; i++)
{
if(rw.Cells[3].Value != null)
{
string strCell3 = rw.Cells[3].Value.ToString();
int intCell3 = 0;
if(int.TryParse(strCell3, out intCell3))
{
if (intCell3 == 4)
{
sc.archive_student(dgv_student_update.Rows[i].Cells[2].Value.ToString(),last_year + " - " + current_year,Convert.ToInt32(dgv_student_update.Rows[i].Cells[1].value));
}
}
else
{
//you decide what to do if its not an integer value
}
}
else
{
//you decide what to do if cell has no value
}
}

Numbered list on Richtextbox

I'm trying to add numbered list functionality to a text editor. RichTextbox already provides the SelectionBullet property to change a selection to a bulleted list. But i was unable to find a similar property to generate numbered list. Is there any standard way to create a numbered list on Richtextbox. If not, i would have to implement it myself so code snips that could help me do that will help, Thank you.
I know that a link is not gernerally accepted as a good answer, however the article RichTextBox with Search Line Numbering, Bulleting, Printing, Searching Support on CodeProject could probably help you out quite a bit with what you are looking for.
In this article, the author extends the RichTextBox control into something that can do what you are asking (and more), plus the code is posted there for all to see.
Well, i implemented it as follows.
private void btnNumbers_Click(object sender, EventArgs e)
{
string temptext = rtbMain.SelectedText;
int SelectionStart = rtbMain.SelectionStart;
int SelectionLength = rtbMain.SelectionLength;
rtbMain.SelectionStart = rtbMain.GetFirstCharIndexOfCurrentLine();
rtbMain.SelectionLength = 0;
rtbMain.SelectedText = "1. ";
int j = 2;
for( int i = SelectionStart; i < SelectionStart + SelectionLength; i++)
if (rtbMain.Text[i] == '\n')
{
rtbMain.SelectionStart = i + 1;
rtbMain.SelectionLength = 0;
rtbMain.SelectedText = j.ToString() + ". ";
j++;
SelectionLength += 3;
}
}
private void rtbMain_KeyDown(object sender, KeyEventArgs e)
{//this piece of code automatically increments the bulleted list when user //presses Enter key
int tempNum;
if (e.KeyCode == Keys.Enter)
try
{
if (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine()]))
{
if (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1]) && rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 2] == '.')
tempNum = int.Parse(rtbMain.Text.Substring(rtbMain.GetFirstCharIndexOfCurrentLine(),2));
else tempNum = int.Parse(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine()].ToString());
if (rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1] == '.' || (char.IsDigit(rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 1]) && rtbMain.Text[rtbMain.GetFirstCharIndexOfCurrentLine() + 2] == '.'))
{
tempNum++;
rtbMain.SelectedText = "\r\n" + tempNum.ToString() + ". ";
e.SuppressKeyPress = true;
}
}
}
catch{}
}
Here is my answer... which is easily readable and refineable. I took a much different approach but added the ability to remove the numbered list within the selection if it already exists. Please note that so far I have only lightly tested it and it seems to work good... but it may need further refinement.
private void btnOrdered_Click(object sender, EventArgs e)
{
string[] splitSelection = null;
// If selection split selection else split everything
if (this.txtCaptionEditor.SelectionLength > 0)
{
splitSelection = this.txtCaptionEditor.SelectedText.Replace("\r\n", "\n").Split("\n".ToCharArray());
}
else
{
splitSelection = this.txtCaptionEditor.Text.Replace("\r\n", "\n").Split("\n".ToCharArray());
}
bool Exists = false;
for (int i = 0; i < splitSelection.GetLength(0); i++)
{
// If Ordered List Allready exists in selection then remove else add
if (!string.IsNullOrEmpty(splitSelection[i]))
{
if (splitSelection[i].Substring(0, 2) == "1.") { Exists = true; }
}
}
for (int i = 0; i < splitSelection.GetLength(0); i++)
{
int lineCount = (i + 1);
if (Exists)
{
this.txtCaptionEditor.Text = this.txtCaptionEditor.Text.Replace(Convert.ToString(lineCount) + ". ", "");
}
else
{
if(!string.IsNullOrEmpty(splitSelection[i]))
{
this.txtCaptionEditor.Text = this.txtCaptionEditor.Text.Replace(splitSelection[i], Convert.ToString(lineCount) + ". " + splitSelection[i]);
}
}
}
}
private void txtCaptionEditor_KeyDown(object sender, KeyEventArgs e)
{
string[] splitSelection = this.txtCaptionEditor.Text.Replace("\r\n", "\n").Split("\n".ToCharArray());
if (e.KeyCode == Keys.Enter)
{
// Get Current Line Position
int currentLine = this.txtCaptionEditor.GetLineFromCharIndex(this.txtCaptionEditor.SelectionStart);
// Only Run if the previous line is greater than zero
if ((currentLine) >= 0)
{
// Loop through 100 possible numbers for match you can go higher
// If you think your numbered list could go above 100
for (int i = 0; i < 100; i++)
{
if (splitSelection[(currentLine)].Substring(0, 2) == Convert.ToString((i + 1)) + ".")
{
// If the substring of the current line equals a numbered list value.. enumerate next line
this.txtCaptionEditor.SelectedText = "\n" + (i + 2) + ". ";
e.SuppressKeyPress = true;
}
}
}
}
}

I need code for FOREACH loop or for loop for four variables

I have four arrays of equal length
I am using those arrays in foreach loops.
I am using four variables(i,j,k,l) to increment and to proceed
I am writing my code inside the four nested loops, that code should execute when i=0,j=0,k=,0,l=0
i=1,j=1,k=1,l=1
i=2,j=2,k=2,l=2
.....(depending on the array length)
Please suggest me the code for this required segment.
int i = 0, j = 0, k = 0, l = 0;
foreach (string fieldName in splitFieldnames)
{
i = 0;
foreach (string dataType in splitDatatypeNames)
{
j = 0;
foreach (string controlName in SplitControlNames)
{
k = 0;
foreach (string controlType in splitControlTypeNames)
{
if (i == j && j == k && k == l)
{
if (controlType == "textbox" && dataType == "string")
{
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
l++;
break;
}
}
k++;
}
j++;
}
i++;
}
}
I think using LINQ would save you a lot of manual coding:
static void Main(string[] args)
{
var splitFieldnames = new string[] { "field1", "field2", "field3" };
var splitDatatypeNames = new string[] { "datatype1", "string", "string" };
var SplitControlNames = new string[] { "control1", "control2", "control3" };
var splitControlTypeNames = new string[] { "combobox", "textbox", "textbox"};
// this code can handle different sized arrays, but is based strictly
// on the size of the splitFieldnames array as the base.
var splitMerged = splitFieldnames.Select
((c, idx) =>
new
{
fieldName = c,
dataType = splitDatatypeNames.Length > idx ?
splitDatatypeNames[idx] : "",
controlName = SplitControlNames.Length > idx ?
SplitControlNames[idx] : "",
controlTypeName = splitControlTypeNames.Length > idx?
splitControlTypeNames[idx] : "",
});
foreach (var item in splitMerged
.Where(c => c.controlTypeName == "textbox" && c.dataType == "string"))
{
Response.Write("_Student." + item.fieldName + "= "
+ item.controlName + ".Text;");
}
The resulting output would be look like:
_Student.field2= control2.Text;
_Student.field3= control3.Text;
I hope that's what you're looking for, LOL...
I think that in this case a DataTable would be better than 4 arrays, and algorithm you require will be trivial with such data structure.
Use for instead of foreach
for (int i = 0; i < splitFieldnames.Length; i++)
{
string fieldName = splitFieldnames[i];
for (int j = 0; j < splitDatatypeNames.Length; j++)
{
string dataType = splitDatatypeNames[j];
for (int k = 0; k < SplitControlNames.Length; k++)
{
string controlName = SplitControlNames[k];
for (int l = 0; l < splitControlTypeNames.Length; l++)
{
string controlType = splitControlTypeNames[l];
if (i == j && j == k && k == l)
{
if (controlType == "textbox" && dataType == "string")
{
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
break;
}
}
}
}
}
}
Note also that break will only break out of the innermost loop! Consider using a return statement instead.
UPDATE (in response to your edit):
The solution is simple, use only one index variable and only one for-loop instead of a lot of foreach-loops
for (int i = 0; i < splitFieldnames.Length; i++)
{
if (splitControlTypeNames[i] == "textbox" && splitDatatypeNames[i] == "string")
{
Response.Write("_Student." + splitFieldnames[i] + "= " + SplitControlNames[i] + ".Text;");
break;
}
}
(Assuming that you want to stop after the first match. If you want to output all string textboxes, drop the break statement.)
Ok, this code is really simple.. If you only need to show the data when i=j=k=l, then no need for any loop, or even for the existence of i,j,k,l.
If you can assure me that all this strings in whatever thing (a collection? an array? a dictionary?) are ordered, is ok.
If they are ordered, then throw away all the for each, and just access each one by position for all the controls you have in the collection that has the minimun.
If all this collection are not ordered, then this is totally uselles, since it will produce differents results on each run.
I will edit this answers with some code, once you can tell me if this is ordered or not.
EDIT:
First of all, you need to check what collection has the least items (since you can't go beyond that)... I don't know the types of this things (you didn't provide them), so let's assume they have a count property.
int minimun = splitFieldnames.count;
if (splitDatatypeNames.count < minimun)
minimun = splitDatatypeNames.count;
if (SplitControlNames.count < minimun)
minimun = SplitControlNames.count
if (splitControlTypeNames.count < minimun)
minimun = splitControlTypeNames.count
once you have the minimun value (since you can't go beyond that), just iterate on that and print whatever you want
for (int i = 0; i < minimun;i++)
{
if (splitControlTypeNames[i].tostring() == "textbox" && splitDatatypeNames[i].tostring() == "string")
{
//Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
//Also, a parametric string would be better ;)
string result = string.format("_Student.{0}= {1}.Text;",splitFieldnames[0].tostring(),SplitControlNames[0].tostring());
Response.Write(result);
l++;
}
}
I don't know the types, so I'm assuming that they have a tostring method an a count property
If what you are trying to accomplish is process the same index in the four arrays, just use one loop and use a counter to access the value in each array in that one loop:
foreach(string fieldName in SplitControlNames)
{
dataType = splitDatatypeNames[arrayPosition];
controlName = SplitControlNames[arrayPosition];
controlType = splitControlTypeNames[arrayPosition];
if (controlType == "textbox" && dataType == "string")
Response.Write("_Student." + fieldName + "= " + controlName + ".Text;");
arrayPosition++;
}
Or, create and populate a structure that has four values in it (fieldName, dataType, controlName, controlType) and have one array of that structure

Autoexpand textbox while typing

I am needing an autoexpanding textbox like facebook has for it's status updates. I have code for it but for some reason it's not fully working correctly. It's updating the textbox and expanding it, but it is doing it way too soon. i am wanting it to expand when it gets to the end of the line. But it is doing it after 20 characters are entered! I have two different methods i have tried, they both do the same thing. Any suggestions on changing my code?
function sz(t) {
var therows = 0
var thetext = document.getElementById(t.id).value;
var newtext = thetext.split("\n");
therows += newtext.length
document.getElementById(t.id).rows = therows;
return false;
}
function sz(t)
{
a = t.value.split('\n');
b = 1;
for (x = 0; x < a.length; x++)
{
if (a[x].length >= t.cols)
{
b += Math.floor(a[x].length / t.cols);
}
}
b += a.length;
if (b > t.rows)
{
t.rows = b;
}
}
Check out this fiddle.
I think your problem was using txtbox.id rather than just passing the id.

Listbox Count error

I'm receiving an error on the 5th line, listCell.Count() tried resolving it with listCell.Items.Count() but that didn't work... any idea? error: does not contain a definition for count.
int listCellCounter = 0;
for (int x = 0; x < listId.Items.Count; x++)
{
Console.WriteLine("something " + listId.Items[x] + " " + listCell.Items[listCellCounter]);
if (listCellCounter == listCell.Count() - 1)
{
listCellCounter = 0;
}
else
{
listCellCounter += 1;
}
}
Im not quite sure what collection the listCell is but I'd imagine that .Count() should be a property. So try to change your code to this:
...
if (listCellCounter == listCell.Count - 1) // or listCell.Items.Count - 1
{
listCellCounter = 0;
}
...
The error you are getting basicly just means that there is no Count() method in listCell.

Categories

Resources