C# ListView Problem Adding Items - c#

So, here's my question: Why won't the code in the first snippet work when the second one works fine. Also, I have set the view property to details. I've read all over how to add lvi's to the listview, and it fails every time... except for then I do it manually.
So, this doesn't work...
// Iterating through the rows...
for (int x = 0; x < numRows; x++) {
row = new List<string>();
// Iterating through the cols...
for (int y = 0; y < numCols; y++) {
row.Add(data[y][x]);
}
lv.Items.Add(new ListViewItem(row.ToArray()));
}
But this will work:
lv.Items.Add(new ListViewItem("foo"));

row.Add(data[y][x]) seems suspicious. Why do you access the data in column-first order but iterate in row-first order? Also, make sure the type of row (you didn't tell us this) is actually List<string>.

The ListViewItem is looking for a String[] try casting row.ToArray() to a String[].

Related

C# ListView - Programatically editing column entries

I'm using a ListView with two columns.
To add new items (into column zero) I'm using:
listView1.Items.Add("Hello")
This results in Hello being present in the column with the lowest index.
However, I'd also like to add in line numbers.
I'm trying this with:
for (int c = 0; c < listView1.Items.Count; c++)
{
listView1.Items[c].SubItems.Clear();
listView1.Items[c].SubItems.Add(c.ToString());
}
The problem, I believe, lies with the main item(s) being cleared even though I'm just attemping to clear() the subitems (i.e. the entry in the second column).
So essentially my question is:
How do I individually edit column entries to be able to display the lines/row numbers?
First item (index 0) in SubItems is actually main item in left column.
If you already added sub item like this listViewItem.SubItems.Add(string.Empty); then you can edit that sub item like this:
for (int c = 0; c < listView1.Items.Count; c++)
{
listView1.Items[c].SubItems[1].Text = c.ToString();
}
I may have solved it...
It may be that once a SubItem is added, the main item is moved to SubItem[0].
The following code seems to be working for me, but I'm not sure if a better way exists.
for (int c = 0; c < listView1.Items.Count; c++)
{
listView1.Items[c].SubItems[0].Text = listView1.Items[c].Text;
listView1.Items[c].SubItems.Add(c.ToString());
listView1.Items[c].SubItems[1].Text = c.ToString();
}

C# Weird Bug when trying to remove Controls from Group Box

I am currently facing a really weird issue. I simply want to remove all controls from a group box, but it just does not remove all controls. It really seems like a bug on Microsoft's end right now. I tried many different techniques of removing these controls, but none of them worked. I have two other methods where I am removing just one Control at a time (and no, I cannot call that in a loop for all my controls) and there it works fine. I have no idea what the issue could be. Hopefully someone knows a way around this.
foreach (Control c in fieldBox.Controls) // this does not work, it only removes my labels (I have one txt and one lbl)
fieldBox.Controls.Remove(c);
for (int i = 0; i < fieldBox.Controls.Count; i++) // this does not work either
fieldBox.Controls.Remove(fieldBox.Controls[i]);
for (int i = 0; i < fieldBox.Controls.Count; i++) // still no success
fieldBox.Controls.RemoveAt(i);
for (int i = 0; i < fieldBox.Controls.Count; i++) // nope
fieldBox.Controls.RemoveByKey(fieldBox.Controls[i].Name);
foreach (Control c in fieldBox.Controls) // my final answer, but the outcome did not change
fieldBox.Controls.RemoveByKey(c.Name);
Try decreasing the counter and removing controls
for (int i = fieldBox.Controls.Count - 1; i >= 0; i--) // hopefully successful
fieldBox.Controls.RemoveAt(i);

How to pass value from a listbox to an empty dropdown list?

I have a listbox which contain some string ... and I would like to pass those string to an empty dropdownlist? Is it possible? Just the value in the listbox will be chosen.
I dont know what I'm doing .. And for this I have to use a for loop which I'm still confused about.
This is my code for now:
string [] lines = new string [cartListBox.Items.Count];
int select;
for (int i = 0; i < lines.Length ; i++)
{
select = cartListBox.SelectedValue
watchedMoviesDropDownList.Items.Add(cartListBox.Items.Count.ToString());
}
However, when I debug it, it gives me an error saying that index is out of range... :( Please help....!
It's much simpler to do it, you don't need:
string [] lines
nor:
int select
Just use this code:
for (int x = 0; x < cartListBox.Items.Count; x++)
watchedMoviesDropDownList.Items.Add(cartListBox.Items[x]);

Row Index provided is out of range, even after check

My current code:
Remove()
{
for (int i = 0; i < ConGridView.RowCount; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
}
So what I am trying to call the remove function every time a client disconnect. the function will remove the connection address from the datagridview. It works well when clients are disconnection one by one. However, if 100 connections gets dropped and it tries to remove 100 connections in less than a second, than it errors out saying "Row Index provided is out of range". How should I check for that ?
So far I've tried:
Try, catch.
if (ConGridView.Rows[i] != null), if (i < ConGridView.RowCount)
None of it seem to work so far. I've also got results using (i < ConGridView.RowCount) where i is 26 while RowCount is 24, but the remove at function still activates..
Any idea on this ?
You can't do this. Your code loops through all the rows in ConGridView, but it deletes them as you do. Therefore, at some point you will try to access an item you have deleted, which will cause the error you described.
Probably the best approach it to iterate through the rows in reverse order. This way, deleting a row at the end won't affect when you access rows at the start.
The problem is you initialise your for loop with the current count of rows and then start removing those same rows from the datagridview. At some point your for loop will try to remove a row at an index that is greater than the number of rows left.
Try this instead:
for (int i = ConGridView.RowCount - 1; i >= 0; i--)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
why dont you get the total count to a separate variable and then iterate
Remove()
{
int totalConnections = ConGridView.RowCount;
for (int i = 0; i < totalConnections ; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
ConGridView.Rows.RemoveAt(i);
break;
}
}
}
This issue is becuase you are modifying the collection your are iterating over. It will be better if you use a temporary array and two loops to remove your entries.
Remove()
// You can use an array/list or whatever you want below.
Collection<DataGridViewRow> rowsToDelete = new Collection<DataGridViewRow>();
for (int i = 0; i < ConGridView.RowCount; i++)
{
if (ConGridView.Rows[i].Cells[0].Value.ToString() == Address)
{
rowsToDelete.Add(ConGridView.Rows[i]);
break;
}
}
// now remove the marked entries.
foreach(DataGridViewRow deletedRow in rowsToDelete)
{
ConGridView.Rows.Remove(deletedRow);
}
When you remove an item from an array, it is reconstructed; shifting the remaining elements up by one to remove the gap of the index you have removed.
1. guybrush threepwood
2. murray
3. elaine
4. Jimmy Gibbs Jr.
If you remove 2. item in here; it becomes this:
1. guybrush threepwood
2. elaine
3. Jimmy Gibbs Jr.
When you are iterating, imagine:
for (int i = 0; i < myArray.Count; i++)
{
if (i == 2) myArray.RemoveAt(i);
}
While running this, when i = 3, the element at 3 has changed, you expect it to be 'elaine' but it is 'Jimmy Gibbs Jr.'. One way to fix this is decrease i by one if we delete it, making sure that i refers to correct value.
for (int i = 0; i < myArray.Count; i++)
{
if (i == 2)
{
myArray.RemoveAt(i);
i--;
}
}
I would go for LINQ in this case, though, everything is easier with that.
myArray.RemoveAll(x => x == "murray");
I've tried all the suggestions posted by everyone here, however, the error was still there.
I've solved the problem using a different way... I've switched to TreeNodeView since that's what I was going to use ultimately. Now I can remove as many connection as i want with:
For each(TreeNode TN in ConTreeView)
{
ConTreeView.Nodes.Remove(TN);
}

Iterating over ListView data

I have a ListView which is bound to a DataTable. I would like to iterate over the DataTable's rows and access their data. I figured, to do this, I would simply iterate over the ListViewDataItems in the ListView. To test that I am properly accessing the data, I tried the following code, which should simply print the string at column 0 for each row.
for (int i = 0; i < MyListView.Items.Count; i++)
{
ListViewDataItem item = MyListView.Items[i];
DataRow row = (DataRow) item.DataItem;
Response.Write(row[0]);
}
However, nothing is printed. To verify that the ListView is not empty (which it shouldn't be as the data is properly rendered on my aspx page), I tried this:
Response.Write(MyListView.Items.Count);
This prints the number 16, which is correct as there are 16 rows in my ListView. I'm guessing I'm just not accessing the data correctly. I'd appreciate some insight on this.
The best way is to stop on breakpoint (at line DataRow row = (DataRow) item.DataItem;) and simply to check what you have .
for example like here :http://msdn.microsoft.com/en-us/library/ms173083(v=VS.90).aspx
I decided the best solution was to just iterate over the data directly in the DataTable rather than the ListViewDataItems.
for (int i = 0; i < myTable.Rows.Count; i++)
{
for (int j = 0; j < myTable.Columns.Count; j++)
{
object data = data.Rows[i][j];
// do stuff with data
}
}
For anyone still seeking the correct answer to this question, the following code will work (VB.NET):
Dim di as ListViewDataItem
For Each di in MyListView.Items
Response.Write(CType(di.FindControl("ExampleLabel"), Label).Text)
Next
Just substitute the Response.Write line with whatever you wanted to do to each list item. The example line is looking for a control called 'ExampleLabel', casts it back to a label then writes the text value onto the page.
Easily adapted to C# for anyone proficient (not I alas).

Categories

Resources