Get single listView SelectedItem - c#

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;
}

Related

c# Check pre-populated Checklistbox Items based on String or List of strings

We have a c# Winforms project in Visual studio 2017.
When a form loads, it populates a checklistbox control with values from the settings.
By default all the items inside the checklistbox are unchecked.
With another button later on we get a string separated by commas for example (apple,oranges,kiwies)
What we want to do is if the item exists in the checklistbox compared with the string we get then to make it checked.
Anyone can help with this ?
You can check a item of a checkListBox with the SetItemCheckState method by using the index of the item inside checkListBox.Items .
You can check if a string exists in checkListBox.Items with the IndexOf method which returns the index of the item that matches the string.
If checkListBox.Items contains the string the desired checkbox will be checked, if not IndexOf will return -1 and no checking will be done. Here is an example:
private void button1_Click(object sender, EventArgs e)
{
string fruit = "apple, oranges, kiwies";
string[] fruitArr = fruit.Split(',').Select(x=>x.Trim()).ToArray();
int index = 0;
foreach (var item in fruitArr)
{
index = checkedListBox1.Items.Cast<string>().ToList().IndexOf(item);
if (index > -1)
{
checkedListBox1.SetItemCheckState(index, CheckState.Checked);
}
}
}
Populating the checkListBox :
private void Form1_Load(object sender, EventArgs e)
{
List<string> fruitList = new List<string>() { "pineapple","banana","apple","oranges" };
foreach (var fruit in fruitList)
{
checkedListBox1.Items.Add(fruit);
}
}

How to get the last selected index or value of checkboxlist

I am using one checkboxlist where i have to check the last selected item index or value.Below is one example:
As we can see in this image orange, pineapple, watermelon is selected. when i used to get this selected item using foreach loop i want to get the last selected item index.
As you didnt provided enough code , assuming that you already have the selectedchangedIndex method .
Try to update your SelectedChangedIndex As follows . This will give the Last selected value of checkboxlist
protected void yourcheckboxlistname_SelectedIndexChanged(object sender, EventArgs e)
{
string value = string.Empty;
string result = Request.Form["__EVENTTARGET"];
string[] checkedBox = result.Split('$'); ;
int index = int.Parse(checkedBox[checkedBox.Length - 1]);
if (yourcheckboxlistname.Items[index].Selected)
{
value = yourcheckboxlistname.Items[index].Value;
}
else
{
}
// For getting the list of values that are selected u can get it like
//this
int lastSelectedIndex = 0;
string lastSelectedValue = string.Empty;
foreach (ListItem listitem in yourcheckboxlistname.Items)
{
if (listitem.Selected)
{
int thisIndex = yourcheckboxlistname.Items.IndexOf(listitem);
if (lastSelectedIndex < thisIndex)
{
lastSelectedIndex = thisIndex;
lastSelectedValue = listitem.Value;
}
}
}
}
Do for loop then put the checked items on the string. The last string will give you the last item, then get its index. Assuming that your items are string in your CheckListBox:
string strGetLastItem = string.Empty;
foreach (object item in checkedListBox1.CheckedItems)
{
strGetLastItem = (string)item;
}
int index = checkedListBox1.Items.IndexOf(strGetLastItem);
//strGetLastItem will give you the last checked item.
//index will get the index of the item
You can create a List to hold the index of the item as its being checked. As an item gets checked, you add the index to the list. The last item checked will be the last index(int) in the list. This will let you know what was checked last.
var lastItemCheckedIndex = checkedItemsList.Count() - 1;
You also want to make sure that the logic that you write accounts for the scenario/event when the checkbox items are being unchecked. Every time an item is being unchecked you remove it from the list. If the last item on the list is removed then you will still be able to determine the last item that was checked prior.

How do I find the amount of items being selected in a ListBox?

I'm trying to find out just how many items are being selected when the user clicks the button.
Here is what I've tried:
private void button1_Click(object sender, EventArgs e)
{
ListItem li;
int x = 0;
foreach ( li in listBox1.Items)
{
if (li.Selected == true)
{
x++;
}
}
}
But instead it's giving me an error.
Type and identifier are both required in a foreach statement
Also, is there a specific method in Windows Form Application that would count the amount of items in a List Box?
There is a method in ListBox class to get the amount of selected item:
int numberSelectedItems = listBox1.SelectedItems.Count;
This gives you the list of selected items. Check the count property istBox1.SelectedItems.Count to get the list of items selected.
var selectedItems = listBox1.SelectedItems;
you can use SelectedIndices or SelectedItems to get the count of selected items like below
listBox1.SelectedIndices.Count
Or
listBox1.SelectedIndices.Count
and Items.Count to get amount of items in a List Box
ListBox1.Items.Count
in yourForeach you need to specify the Type, Try below
int x = 0;
foreach(ListItem item in ListBox1.Items)
{
if (item.Selected)
x++;
}

Cloning items in a listbox c#

I have 2 list boxes and want to be able to copy selected items from one to the other how ever many times I want. Ive managed to do this but I have buttons on the 2nd list box that allow me to go up and down..Now when theres to items in the second list box that are the same (e.g "gills" and "gills") it doesnt behave normally and crashes.
Is there a way in which I can get them to act as seperate items in the 2nd listbox?
code
private void buttonUp_Click(object sender, EventArgs e)
{
object selected = listBox2.SelectedItem;
int index = list2.Items.IndexOf(selected);
listBox2.Items.Remove(selected);
listBox2.Items.Insert(index - 1, selected);
listBox2.SetSelected(index - 1, true);
}
private void buttonAdd_Click(object sender, EventArgs e)
{
DataRowView selected = (DataRowView)listBox1.SelectedItem;
string item = selected["title"].ToString();
listBox2.Items.Add(item);
}
It works fine when i havnt got duplicates but when i do they just jump around randomly when i press up/down.
(ive not included down as its pretty much the same as up)
It seems like you're travelling around the world to do something simple. I would approach this using List and databinding the list.
// Add code
DataRowView selected = listBox1.SelectedItem as DataRowView;
if (selected != null)
{
_myList.Add(selected); // Adds at end
BindList2();
}
// Move up code
int selectedIndex = listBox2.SelectedIndex;
if(selectedIndex > 0)
{
var temp = _myList[selectedIndex];
_myList.Remove(temp);
_myList.InsertAt(selectedIndex - 1, temp);
BindList2();
}
// BindList2
public void BindList2()
{
listBox2.DataSource = _myList;
listBox2.DataBind();
}
You can use SelectedIndex instead of SelectedItem when you have multiple items that are all equal. I also recommend checking that it's not -1.
The problem for the up case is the following set of code.
object selected = listBox2.SelectedItem;
int index = list2.Items.IndexOf(selected);
This code will only function correctly if you have unique items in the list. Once you have duplicate items the value index will be the index of the first instance of say gills in the list and not necessarily the index of the selected value.
It seems like you mirror the items in listBox2 and list2. If that is the case then you can just use the SelectedIndex property directly on listBox2 since the index will be equal in both liss.
int index = listBox2.SelectedIndex;
If you are trying to use an list of objects, try implementing the Iclonnable. This will make copies of the same item over & over. Also note to move an item to the top or bottom you don't have to remove the item in the list & reinsert them back. But you can change the index of the item. Hope this helps.
Just the code, because the rest of the answers cover it anyways:
private void buttonAdd_Click(object sender, EventArgs e)
{
DataRowView selected = listBox1.SelectedItem as DataRowView;
if (selected != null)
{
string item = selected["title"].ToString();
listBox2.Items.Add(item);
}
}
private void buttonUp_Click(object sender, EventArgs e)
{
string selected = listBox2.SelectedItem as string;
int oldIndex = listBox2.SelectedIndex;
int newIndex = oldIndex;
if (!string.IsNullOrEmpty(selected) && listBox2.Items.Count > 1 && oldIndex > 0)
{
listBox2.SuspendLayout();
listBox2.Items.RemoveAt(oldIndex);
newIndex = oldIndex - 1;
listBox2.Items.Insert(newIndex, selected);
listBox2.SelectedIndex = newIndex;
listBox2.ResumeLayout();
}
}

C# On_buttonClick, remove null contents from listbox

How do I setup a button click to remove only null contents from a listbox and keep the listbox populated.
Example:
Work
Files
here
Armor
Result (on_button_click,changes listbox):
Work
Files
here
Armor
Any help always appricated.
You need to loop backwards through the items in the ListBox and remove the items that you don't like.
For example:
for (int i = listBox.Items.Count - 1; i >= 0; i--) {
if (String.IsNullOrEmpty(listBox.Items[i] as String))
listBox.Items.RemoveAt(i);
}
The loop needs to be backwards because otherwise, all of the upcoming indices will move down.
Maybe something like this?
Whoops, as noted, you cannot iterate through a collection and modify it at the same time. Therefore, I present some Frankenstein code:
private void OnButtonClick(object sender, EventArgs e)
{
List<String> removeMe = new List<String>();
foreach(String x in listBox.Items)
{
if (String.IsNullOrEmpty(x))
{
removeMe.Add(x);
}
}
foreach(String x in removeMe)
{
listBox.Items.Remove(x);
}
}

Categories