Tag problem c# listbox - c#

Hi i'm trying to use the tag item of a listbox.
heres my code.
int number = 0;
foreach (ListViewItem item in listBox1.Items)
{
Tag tag = (Tag) item.Tag;
saveSlide(showid, tag.photoid, enumber);
number++;
}
problem im havin is when i run the program i get an error message sayin cannot convert type string to system.ListView but i haven't declared item as a string anywher in my program
This is where i add the items to the listbox. Please help. Im on a dead line and have sooo much more to do
private void buttonAdd_Click(object sender, EventArgs e)
{
//add selected item into listBox
DataRowView drv = (DataRowView)listBox1.SelectedItem;
Tag tag = new Tag();
string title = drv["title"].ToString();
ListViewItem item = new ListViewItem(title);
item.Tag = tag;
tag.photoid = (int)drv["photoid"];
listBox1.Items.Add(title);
}

Poppy you are adding title to listBox1.Items.
title is of type string.
So when you access it use string type like this foreach (string item in listBox1.Items).
Try. Does it help?
int number = 0;
foreach (string item in listBox1.Items)
{
Tag tag = (Tag) item.Tag;
saveSlide(showid, tag.photoid, enumber);
number++;
}

This works, you need to show the code where you add items to the list:
private class Tag
{
public override string ToString()
{
return "Tag";
}
}
ListBox listBox = new ListBox();
listBox.Items.Add(new ListViewItem { Tag = new Tag() });
foreach (ListViewItem item in listBox.Items)
{
Tag tag = (Tag)item.Tag;
Console.WriteLine(tag);
}
Edit following more code:
You are adding strings to your ListBox instead of the ListViewItem:
listBox1.Items.Add(title); should be listBox1.Items.Add(item);

ListBox.Items is an ObjectCollection. That means you can choose the kind of object to put in it.
When you're doing this:
string title = drv["title"].ToString();
listBox1.Items.Add(title);
you are putting string objects into it, so you would need to get them out like this:
foreach (string item in listBox1.Items)
Instead, you probably want your code to be more like this:
ListViewItem item = new ListViewItem(title);
item.Tag = tag;
tag.photoid = (int)drv["photoid"];
listBox1.Items.Add(item); // The difference is here - add *item* not *title*
then you'll be able to use this the way you initially wrote it:
foreach (ListViewItem item in listBox1.Items)

Does Tag has a member named photoid? Maybe you need a cast in there to convert your 'tag' to whatever it's supposed to be?
//Tag tag = (Tag) item.Tag;
MyObject tag = (MyObject)item.Tag;
saveSlide(showid, tag.photoid, enumber);
number++;

Unless you named things weird I'd say the error is that you're trying to get a ListViewItem from a ListBox.

Just change the last line of code of the second code-snippet and everything will be ok, which is as follows.
listBox1.Items.Add(item);
About the Error
You added strings to the listBox as items and in the foreach an item(which is a string) is tried to convert(caste) to ListViewItem implicitly to hich doesn't work and the compiler gives the error.
Hope it will work.

Related

c# loop listbox selected items

I have a listbox on a form set to allow multiple selections. I want to loop through each selected item, store the selected value in a variable and do some work. I've tried many different variations of code to do this, but so far nothing has worked. Any help would be greatly appreciated! My code is below:
foreach (var item in systemList.Items)
{
string systemName = systemList.SelectedItems.ToString();
//do some work//
}
You can get all SelectedItems using below code:
var items = systemList.Items.Cast<ListItem>().Where(item => item.Selected);
You can then loop through the items
foreach (var item in items)
{
//Access value of each item by calling item.Value
}
foreach (var item in systemList.SelectedItems)
{
string systemName = item.ToString();
//do some work//
}
make sure listbox Selection mode is set to other than single!

How to display form variables based on variable name

I have a list of variable names, lets say:
List<string> list = new List<string>();
list.Add("size");
list.Add("width");
list.Add("name");
list.Add("zip");
and i have text controls with those exact names, is there a way to loop through the list and only display what the value of the text control that i am asking for, like lets say something like this:
foreach (string txtctl in list)
{
Response.Write(Request.Form[txtctl]);
}
When i run this code the value just displays blank. Any suggestions?
string str = "";
foreach (string item in list)
{
TextBox txt = (TextBox)Form.FindControl(item);
if (txt != null)
{
str += item+":"+ txt.Text+"<br>";
}
}
Response.Write(str);

Get single listView SelectedItem

I have the MultiSelect property of the listView set to false and I'm trying to get a single listViewItem. But the available property is SelectedItems. I've been using the following code...
foreach (ListViewItem item in listView1.SelectedItems)
{
//do something with item.text or whatever
}
Because I know there will only be one item selected. What is the correct way of doing this?
Usually SelectedItems returns either a collection, an array or an IQueryable.
Either way you can access items via the index as with an array:
String text = listView1.SelectedItems[0].Text;
By the way, you can save an item you want to look at into a variable, and check its structure in the locals after setting a breakpoint.
I do this like that:
if (listView1.SelectedItems.Count > 0)
{
var item = listView1.SelectedItems[0];
//rest of your logic
}
Sometimes using only the line below throws me an Exception,
String text = listView1.SelectedItems[0].Text;
so I use this code below:
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedIndices.Count <= 0)
{
return;
}
int intselectedindex = listView1.SelectedIndices[0];
if (intselectedindex >= 0)
{
String text = listView1.Items[intselectedindex].Text;
//do something
//MessageBox.Show(listView1.Items[intselectedindex].Text);
}
}
If its just a natty little app with one or two ListViews I normally just create a little helper property:
private ListViewItem SelectedItem { get { return (listView1.SelectedItems.Count > 0 ? listView1.SelectedItems[0] : null); } }
If I have loads, then move it out to a helper class:
internal static class ListViewEx
{
internal static ListViewItem GetSelectedItem(this ListView listView1)
{
return (listView1.SelectedItems.Count > 0 ? listView1.SelectedItems[0] : null);
}
}
so:
ListViewItem item = lstFixtures.GetSelectedItem();
The ListView interface is a bit rubbish so I normally find the helper class grows quite quickly.
For a shopping cart situation here's what I recommend. I'm gonna break it down into it's simplest form.
Assuming we start with this(a list view with 2 colums, 2 buttons, and a label):
First things first, removing the items, to do that we'll enter our remove button:
private void button2_Click(object sender, EventArgs e)
{
listView1.Items.Remove(listView1.SelectedItems[0]);
label1.Text = updateCartTotal().ToString();
}
Now the second line is updating our labels total using the next function i'll post to addup all the total of column 2 in the listview:
private decimal updateCartTotal()
{
decimal runningTotal = 0;
foreach(ListViewItem l in listView1.Items)
{
runningTotal += Convert.ToDecimal(l.SubItems[1].Text);
}
return runningTotal;
}
You don't have to use decimal like I did, you can use float or int if you don't have decimals. So let's break it down. We use a for loop to total all the items in the column 2(SubItems[1].Text). Add that to a decimal we declared prior to the foreach loop to keep a total. If you want to do tax you can do something like:
return runningTotal * 1.15;
or whatever your tax rate is.
Long and short of it, using this function you can retotal your listview by just calling the function. You can change the labels text like I demo'd prior if that's what you're after.
None of the answers above, at least to me, show how to actually handle determining whether you have 1 item or multiple, and how to actually get the values out of your items in a generic way that doesn't depend on there actually only being one item, or multiple, so I'm throwing my hat in the ring.
This is quite easily and generically done by checking your count to see that you have at least one item, then doing a foreach loop on the .SelectedItems, casting each item as a DataRowView:
if (listView1.SelectedItems.Count > 0)
{
foreach (DataRowView drv in listView1.SelectedItems)
{
string firstColumn = drv.Row[0] != null ? drv.Row[0].ToString() : String.Empty;
string secondColumn = drv.Row[1] != null ? drv.Row[1].ToString() : String.Empty;
// ... do something with these values before they are replaced
// by the next run of the loop that will get the next row
}
}
This will work, whether you have 1 item or many. It's funny that MSDN says to use ListView.SelectedListViewItemCollection to capture listView1.SelectedItems and iterate through that, but I found that this gave an error in my WPF app: The type name 'SelectedListViewItemCollection' does not exist in type 'ListView'.
foreach (ListViewItem itemRow in taskShowListView.Items)
{
if (itemRow.Items[0].Checked == true)
{
int taskId = Convert.ToInt32(itemRow.SubItems[0].Text);
string taskDate = itemRow.SubItems[1].ToString();
string taskDescription = itemRow.SubItems[2].ToString();
}
}
If you want to select single listview item no mouse click over it try this.
private void timeTable_listView_MouseUp(object sender, MouseEventArgs e)
{
Point mousePos = timeTable_listView.PointToClient(Control.MousePosition);
ListViewHitTestInfo hitTest = timeTable_listView.HitTest(mousePos);
try
{
int columnIndex = hitTest.Item.SubItems.IndexOf(hitTest.SubItem);
edit_textBox.Text = timeTable_listView.SelectedItems[0].SubItems[columnIndex].Text;
}
catch(Exception)
{
}
}
This works for single as well as multi selection list:
foreach (ListViewItem item in listView1.SelectedItems)
{
int index = item.Index;
//index is now zero based index of selected item
}
On mouse click, I would do it like this:
public static string GetSelectedItem(ListView list)
{
foreach (ListViewItem item in list.Items)
{
if (item.Selected)
return item.Text;
}
return null;
}

C#: How to add subitems in ListView

Creating an item(Under the key) is easy,but how to add subitems(Value)?
listView1.Columns.Add("Key");
listView1.Columns.Add("Value");
listView1.Items.Add("sdasdasdasd");
//How to add "asdasdasd" under value?
You whack the subitems into an array and add the array as a list item.
The order in which you add values to the array dictates the column they appear under so think of your sub item headings as [0],[1],[2] etc.
Here's a code sample:
//In this example an array of three items is added to a three column listview
string[] saLvwItem = new string[3];
foreach (string wholeitem in listofitems)
{
saLvwItem[0] = "Status Message";
saLvwItem[1] = wholeitem;
saLvwItem[2] = DateTime.Now.ToString("dddd dd/MM/yyyy - HH:mm:ss");
ListViewItem lvi = new ListViewItem(saLvwItem);
lvwMyListView.Items.Add(lvi);
}
Like this:
ListViewItem lvi = new ListViewItem();
lvi.SubItems.Add("SubItem");
listView1.Items.Add(lvi);
Suppose you have a List Collection containing many items to show in a ListView, take the following example that iterates through the List Collection:
foreach (Inspection inspection in anInspector.getInspections())
{
ListViewItem item = new ListViewItem();
item.Text=anInspector.getInspectorName().ToString();
item.SubItems.Add(inspection.getInspectionDate().ToShortDateString());
item.SubItems.Add(inspection.getHouse().getAddress().ToString());
item.SubItems.Add(inspection.getHouse().getValue().ToString("C"));
listView1.Items.Add(item);
}
That code produces the following output in the ListView (of course depending how many items you have in the List Collection):
Basically the first column is a listviewitem containing many subitems (other columns). It may seem strange but listview is very flexible, you could even build a windows-like file explorer with it!
I've refined this using an extension method on the ListViewItemsCollection. In my opinion it makes the calling code more concise and also promotes more general reuse.
internal static class ListViewItemCollectionExtender
{
internal static void AddWithTextAndSubItems(
this ListView.ListViewItemCollection col,
string text, params string[] subItems)
{
var item = new ListViewItem(text);
foreach (var subItem in subItems)
{
item.SubItems.Add(subItem);
}
col.Add(item);
}
}
Calling the AddWithTextAndSubItems looks like this:
// can have many sub items as it's string array
myListViewControl.Items.AddWithTextAndSubItems("Text", "Sub Item 1", "Sub Item 2");
Hope this helps!
I think the quickest/neatest way to do this:
For each class have string[] obj.ToListViewItem() method and then do this:
foreach(var item in personList)
{
listView1.Items.Add(new ListViewItem(item.ToListViewItem()));
}
Here is an example definition
public class Person
{
public string Name { get; set; }
public string Address { get; set; }
public DateTime DOB { get; set; }
public uint ID { get; set; }
public string[] ToListViewItem()
{
return new string[] {
ID.ToString("000000"),
Name,
Address,
DOB.ToShortDateString()
};
}
}
As an added bonus you can have a static method that returns ColumnHeader[] list for setting up the listview columns with
listView1.Columns.AddRange(Person.ListViewHeaders());
Create a listview item
ListViewItem item1 = new ListViewItem("sdasdasdasd", 0)
item1.SubItems.Add("asdasdasd")
ListViewItem item = new ListViewItem();
item.Text = "fdfdfd";
item.SubItems.Add ("melp");
listView.Items.Add(item);
add:
.SubItems.Add("asdasdasd");
to the last line of your code so it will look like this in the end.
listView1.Items.Add("sdasdasdasd").SubItems.Add("asdasdasd");
Generally:
ListViewItem item = new ListViewItem("Column1Text")
{ Tag = optionalRefToSourceObject };
item.SubItems.Add("Column2Text");
item.SubItems.Add("Column3Text");
myListView.Items.Add(item);
Great !! It has helped me a lot. I used to do the same using VB6 but now it is completely different.
we should add this
listView1.View = System.Windows.Forms.View.Details;
listView1.GridLines = true;
listView1.FullRowSelect = true;

Copy items from ListBox to CheckedListBox

There are many questions that ask the opposite of this question, unfortunately none of them have worked for me. I have the following code to achieve my purpose:
foreach (var item in listBox1.Items)
{
checkedListBox1.Items.Add(item);
}
The problem is that when I do this, I don't get the values inside the ListBox, rather the System.Data.DataRowView items. So my CheckedListBox gets populated with exactly this, System.Data.DataRowView strings, which are all the same and don't show the actual string value.
Edit: I bind to the ListView this way: I have a DataTable ds, and:
listBox1.DataSource = ds;
For some unknown reason, DataSource, DisplayMember and ValueMember properties are hidden for CheckedListBox control.
If you want to copy the the list box items text, the correct way is to use ListControl.GetItemText method like this
foreach (var item in listBox1.Items)
checkedListBox1.Items.Add(listBox1.GetItemText(item));
But this way it will be hard to find which source object is checked (for instance when enumerating CheckedItems). A better way would be to define your own class like this
class MyListItem
{
public object Value;
public string Text;
public override string ToString() { return Text; }
}
and use
foreach (var item in listBox1.Items)
checkedListBox1.Items.Add(new MyListItem { Value = item, Text = listBox1.GetItemText(item) });
Try this:
foreach (var dataRowView in listBox1.Items.OfType<DataRowView>())
{
checkedListBox1.Items.Add(dataRowView[0].ToString());
}
The text displayed by derived ListControl classes like a CheckedListBox, when these controls are binded to a datasource, is ruled by the property DisplayMember. This property equals to a string representing the name of a property (or a columnname) in the datasource.
So before adding the new items to your checkedlistbox I suggest to write
checkedListBox1.DataSource = listBox1.DataSource
checkedListBox1.DisplayMember = listBox1.DisplayMember
checkedListBox1.ValueMember = listBox1.ValueMember
And no need to create a loop reading all the items from the source listbox, just use the same datasource and your are ready
You need to do a cast like the following :
foreach (var item in listBox1.Items)
{
checkedListBox1.Items.Add((ListItem)item);
}
or else you can use like this:
foreach (ListItem item in listBox1.Items)
{
checkedListBox1.Items.Add(item);
}
even this also may help you(use like this if you want text and value);
for(int i=0;i<listBox1.Items.Count-1;i++)
{
checkedListBox1.Items.Add(new ListItem() { Text = listBox1.Items[i].Text, Value = listBox1.Items[i].Text });
}

Categories