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.
Related
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
}
}
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.
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
4th time asking this question after trying to apply so fixes. My problem is I have 2 listboxs one holds IDs and the other holds Cell ids. The ID listbox has 10 items (for testing) and Cell boxes have 5 ID. I'm trying to process listId and listCell at the same time creating update links...
example MakeReq will create txtWebUpdate.Text listID listCell &ire=1, in which is
store.domain.com/101/sec01&ire=1
store.domain.com/102/sec02&ire=1
store.domain.com/103/sec03&ire=1
store.domain.com/104/sec04&ire=1
store.domain.com/105/sec05&ire=1
store.domain.com/106/sec01&ire=1 <- notice how listCell starts over it
continues to loop applying sections until the ListID is complete.
here's the code i've been working with. what's happening with my code is that it's only selecting the first item. It's not going to the next item after its done.
if (listId.Items.Count != 0 && listCell.Items.Count != 0)
{
for (int a = 0; a < listId.Items.Count; a++)
{
for (int b = 0; b < listCell.Items.Count; b++)
{
lblID.Text = listId.Items[a].ToString();
MakeReq(txtWebUpdate.Text + listId.Items[a].ToString() +
"&ire=1", listCell.Items[b].ToString());
//System.Threading.Thread.Sleep(5);
}
}
}
Please only comment if you can help. I'm almost positive that the problem is the for statement and how it's selecting list items, but I may be wrong.
Edit More Info: after testing an example/suggestion for #duffp below the problem is definitely with my For statements. What's happening is its counting that I have 5 entries in ListCell and then output one (the same) ListID 5times but with a different ListCell. Can someone help me write it following what I wrong above?
It may have something to do within the MakeReq method call. I just tried the following code:
private void Form1_Load(object sender, EventArgs e)
{
if (listId.Items.Count != 0 && listCell.Items.Count != 0)
{
for (int a = 0; a < listId.Items.Count; a++)
{
for (int b = 0; b < listCell.Items.Count; b++)
{
lblID.Text = listId.Items[a].ToString();
MakeReq(listId.Items[a].ToString(), listCell.Items[b].ToString());
}
}
}
}
public void MakeReq(string listId, string cellId)
{
Console.WriteLine("store.domain.com/" + listId + "sec01&ire=" + cellId);
}
And it gave the output:
store.domain.com/ID_10sec01&ire=Cell_1
store.domain.com/ID_10sec01&ire=Cell_2
store.domain.com/ID_10sec01&ire=Cell_3
store.domain.com/ID_10sec01&ire=Cell_4
store.domain.com/ID_10sec01&ire=Cell_5
store.domain.com/ID_10sec01&ire=Cell_6
store.domain.com/ID_10sec01&ire=Cell_7
store.domain.com/ID_10sec01&ire=Cell_8
store.domain.com/ID_10sec01&ire=Cell_9
store.domain.com/ID_10sec01&ire=Cell_10
Isn't that what you wanted?
I think there might be some side-effects in MakeReq that you are not showing us. How about adding some debug statements to your code, like this:
if (listId.Items.Count != 0 && listCell.Items.Count != 0)
{
for (int a = 0; a < listId.Items.Count; a++)
{
int listCellCount = listCell.Items.Count;
for (int b = 0; b < listCell.Items.Count; b++)
{
lblID.Text = listId.Items[a].ToString();
MakeReq(txtWebUpdate.Text + listId.Items[a].ToString() +
"&ire=1", listCell.Items[b].ToString());
//System.Threading.Thread.Sleep(5);
Debug.Assert(listCellCount == listCell.Items.Count);
}
}
}
The assertion (listCellCount == listCell.Items.Count) should always be true, unless something is changing listCell.Items.
This application works as if you were playing the lottery, you pick 5 numbers from a comboBox, click a button to generate the 5 key numbers and then you press another button to check the results (after you introduce the prize monei on the textbox below, AKA "prémio").
The button that does the checking is the highlighted one Verificar Prémio.
Here's it's code:
private void button5_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" && textBox1.Text!="Prémio em €")
{
int contador = 0;
for (int i = 1; i <= 5; i++)
{
string posicao = i.ToString();
for (int c = 1; c <= 5; c++)
{
string poschave = c.ToString();
if (listBox1.Items.IndexOf(posicao) ==
listBox2.Items.IndexOf(poschave))
{
contador = contador + 1;
}
}
i = int.Parse(posicao);
double valor;
double premio = double.Parse(textBox1.Text);
if (contador == 5)
{
MessageBox.Show(" Parabens ganhou o 1º premio acertou 5 números
o seu prémio é de " + premio + "€");
}
else
{
if (contador == 4)
{
valor = premio * 0.75;
MessageBox.Show(" Acertou 4 numeros o seu premio é: " +
valor + "€");
}
else
{
if (contador == 3)
{
valor = premio * 0.5;
MessageBox.Show("Acertou 3 numeros o seu premio é: " +
valor + "€");
}
else
if (contador <= 2)
{
MessageBox.Show(" Infelizmente nao ganhou,
nada tente outra vez");
}
}
}
}
}
}
Whatever I do, it always shows the messageBox saying I got all 5 correct...
EDIT:
listBox1 is the one on the left, (3, 9, 17, 20, 10), you choose them from the combobox and when you Click "Apostar" it is added to it.
listBox2 is the box on the right.
EDIT2:
By replacing
for (int c = 1; c <= 5; c++)
{
string poschave = c.ToString();
if (listBox1.Items.IndexOf(posicao) == listBox2.Items.IndexOf(poschave))
{
contador = contador + 1;
}
}
with
foreach (var item in listBox1.Items)
{
// Convert it to string to avoid object reference comparison. Not 100%
// sure if this is needed
string value = item.ToString();
if (listBox2.Items.Contains(value))
contador++;
}
The error doesnt show anymore however it still isnt working properly, my guess is that the program is checking if they match, then get the result, therefore it always show "you won nothing" 5 times in a row...
How can I fix this?
I don't understand Spanish(?) so it's very hard to understand your code (please use english variable names, even if you have a localized UI)
However, one cause of the problem could be this line:
listBox1.Items.IndexOf(posicao) == listBox2.Items.IndexOf(poschave)
In case neither posicao or poschave is found in their respective listboxes, -1 will be returned and the expression will be true (i.e. contador will be incremented). I'm guessing this is not the desired behavior.
If you instead want to check if an item in the left listbox is also available in the right, then you could do:
void Button_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || textBox1.Text == "Prémio em €")
return;
int numMatches = 0;
foreach (var item in listBox1.Items)
{
if (listBox2.Items.Contains(item))
numMatches++;
}
// numMatches will now contain the number of elements in the left
// listbox that also exist in the right listbox
if (numMatches > 2)
{
double premio = Double.Parse(textBox1.Text);
double prize = 0;
if (numMatches == 5)
prize = premio * 1.0;
if (numMatches == 4)
prize = premio * 0.75;
else
prize = premio * 0.5;
// Use string.Format() instead to get fancier formatting of numbers
Messagebox.Show ("Sweet, you got " + numMatches + " out of 5 correct numbers. Your prize is " + prize + "€");
}
else
{
MessageBox.Show("Sorry, not enough matches - you win nothing!");
}
}
EDIT:
The reason you get 5 message boxes is because you have the call to Messagebox.Show() inside a for loop that loops five times. I've updated the code sample above to do what I think you want your button callback to do
Your source is way too complicated, you have two loops, one integer > string followed by string > integer... try this:
int count = 0;
for (int i = 0; i < 5; i++)
{
if (listBox2.Items.IndexOf(listBox1.Items[i]) > 0)
{
count++;
}
}
// count is 0 - 5
You only check for 5 numbers of the left ListBox if it is in the right ListBox.