I have a multiselection listbox. I want to see the last selected item (which the user just selected). I can't find any way to do this googling..
Thanks in advance.
I have a multiselection listbox. I want to see the last selected item (which the user just selected). I can't find any way to do this googling..
Thanks in advance.
Here's a solution. Version 2 code has been tested.
Create a new class called "ItemInfo". Replace with the following code:
ItemInfo:
public class ItemInfo
{
public string Name { get; set; }
public string SelectionType { get; set; }
}
In your form, (ex: Form1.cs), do the following:
Create a list to hold the previously selected items and an instance of ItemInfo.
public partial class Form1 : Form
{
List<string> previousSelectedItemsList = new List<string>();
ItemInfo lastItem = new ItemInfo();
public Form1()
{
InitializeComponent();
}
}
Then we create a method to find the last selected item:
Version 1
(keeps track of last selected item):
private void getLastItemChanged(ref ListBox lb)
{
List<string> lastItemSelected;
List<string> currentSelectedItemsList = new List<string>();
//put selected items into a list
//so we can use list.except
for (int i = 0; i < lb.SelectedItems.Count; i++)
{
//add selected items to list
currentSelectedItemsList.Add(lb.SelectedItems[i].ToString());
//Console.WriteLine("item: " + lb.SelectedItems[i]);
}//for
//get last item selected as a list
//by comparing the current list
//to the previous list
lastItemSelected = currentSelectedItemsList.Except(previousSelectedItemsList).ToList();
//if last item was selected count > 0
//else if last item was de-selected
//lastItemSelected.Count = -1
if (lastItemSelected.Count > 0)
{
lastItem.Name = lastItemSelected[0].ToString();
lastItem.SelectionType = "selected";
}//if
Console.WriteLine(lastItem.Name + " : " + lastItem.SelectionType);
//updated previousSelectedItems before returning
previousSelectedItemsList = currentSelectedItemsList;
}//getLastItemChanged
Version 2
(keeps track of last item - selected OR de-selected):
private void getLastItemChanged(ref ListBox lb)
{
List<string> lastItemSelected;
List<string> lastItemDeSelected;
List<string> currentSelectedItemsList = new List<string>();
//put selected items into a list
//so we can use list.Except
for (int i = 0; i < lb.SelectedItems.Count; i++)
{
//add selected items to list
currentSelectedItemsList.Add(lb.SelectedItems[i].ToString());
//Console.WriteLine("item: " + lb.SelectedItems[i]);
}//for
//get last item selected as a list
//by comparing the current list
//to the previous list
lastItemSelected = currentSelectedItemsList.Except(previousSelectedItemsList).ToList();
//if last item was selected count > 0
//else if last item was de-selected
//lastItemSelected.Count = -1
if (lastItemSelected.Count > 0)
{
lastItem.Name = lastItemSelected[0].ToString();
lastItem.SelectionType = "selected";
}//if
else
{
//if item was deselected, switch the order
//compare previous list to current list
lastItemDeSelected = previousSelectedItemsList.Except(currentSelectedItemsList).ToList();
//if > 0, last item was de-selected
if (lastItemDeSelected.Count > 0)
{
lastItem.Name = lastItemDeSelected[0].ToString();
lastItem.SelectionType = "de-selected";
}//if
}//else
Console.WriteLine(lastItem.Name + " : " + lastItem.SelectionType);
//updated previousSelectedItems before returning
previousSelectedItemsList = currentSelectedItemsList;
}//getLastItemChanged
Then in the ListBox SelectedValueChanged event handler (ex: listBox1_SelectedValueChanged), we call "getLastItemChanged":
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
getLastItemChanged(ref listBox1);
}
List.Except code adapted from here.
I re-worked the above code to create a version that allows you to specify if you want the last "Selected" item, the last "De-selected" item, or last item that was changed (either "Selected" or "De-selected").
Create a new class called "ItemInfo". Replace the code with the following:
ItemInfo:
public class ItemInfo
{
public string Name { get; set; }
public string SelectionType { get; set; }
}
In the form (Form1), create a list, a new instance of ItemInfo, and an enum as seen below:
public partial class Form1 : Form
{
//holds previously selected items
List<string> previousSelectedItemsList = new List<string>();
//holds the last selected and/or de-selected item
ItemInfo lastItem = new ItemInfo();
//create an enumeration
enum SelectionType { Deselected, Either, Selected };
public Form1()
{
InitializeComponent();
}
}
Now, we will create a method that will compare our lists and return an ItemInfo object:
private ItemInfo findExcludedItemInList(List<string> list1, List<string> list2)
{
ItemInfo item = new ItemInfo();
//get list of items in list1 that aren't in list2
var lastItemList1 = list1.Except(list2).ToList();
if (lastItemList1.Count > 0)
{
//there should only be 1 item in the list
item.Name = lastItemList1[0].ToString();
item.SelectionType = "Selected";
}//if
else
{
//get list of items in list2 that aren't in list1
var lastItemList2 = list2.Except(list1).ToList();
if (lastItemList2.Count > 0)
{
//there should only be 1 item in the list
item.Name = lastItemList2[0].ToString();
item.SelectionType = "Deselected";
}//if
}//else
return item;
}//findExcludedItemInList
Next, we will create a method "getLastItemChanged" that will use "findExcludedItemInList".
private void getLastItemChanged(ref ListBox lb, ref ItemInfo lastItem, ref List<string> previousSelectedItemsList, SelectionType sType)
{
List<string> currentSelectedItemsList = new List<string>();
//put selected items into a list
//so we can use list.Except
for (int i = 0; i < lb.SelectedItems.Count; i++)
{
currentSelectedItemsList.Add(lb.SelectedItems[i].ToString());
//Console.WriteLine("item: " + lb.SelectedItems[i]);
}//for
if (sType.Equals(SelectionType.Either))
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
Console.WriteLine(lastItem.Name + " : " + lastItem.SelectionType);
}//if
else if (sType.Equals(SelectionType.Selected))
{
//get last item selected as a list
//by comparing the current list
//to the previous list
if (String.Compare(findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList).SelectionType, "Selected", true) == 0)
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
Console.WriteLine(lastItem.Name + " : " + lastItem.SelectionType);
}//if
}//else if
else if (sType.Equals(SelectionType.Deselected))
{
//if item was deselected, switch the order
//compare previous list to current list
//if > 0, last item was de-selected
if (String.Compare(findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList).SelectionType, "Deselected", true) == 0)
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
Console.WriteLine(lastItem.Name + " : " + lastItem.SelectionType);
}//if
}//else if
//updated previousSelectedItems before returning
previousSelectedItemsList = currentSelectedItemsList;
}//getLastItemChanged
Then in the ListBox SelectedValueChanged event handler (ex: listBox1_SelectedValueChanged), we call "getLastItemChanged":
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
//get only last selected item
//getLastItemChanged(ref listBox1, ref lastItem, ref previousSelectedItemsList, SelectionType.Selected);
//get only last Deselected item
//getLastItemChanged(ref listBox1, ref lastItem, ref previousSelectedItemsList, SelectionType.Deselected);
//get last changed item - Selected or Deselected
getLastItemChanged(ref listBox1, ref lastItem, ref previousSelectedItemsList, SelectionType.Either);
Console.WriteLine("lastItem: " + lastItem.Name + " Type: " + lastItem.SelectionType);
}
There is no need to pass any of that stuff by reference, remove it all. You mix modes (windows controls writing to the console). Your methods have overly complicated signatures and almost all that code (if not all of it) should be inside a different class, not in your form. It is a ListBox monitor, code it as such.
Tough crowd. The Console.WriteLine statements were for debugging. I left them in so that one could verify the results. They should be removed when finished debugging.
Here is an updated version:
The concept of the code is the same. However, I moved the majority of the code to it's own class: ListBoxMonitor. "getLastItemChanged" now returns an "ItemInfo" object. I removed some parameters from "getLastItemChanged" and made them private variables in class ListBoxMonitor. I've also made ListBoxMonitor static.
Create a new class called "ListBoxMonitor.cs" and replace with the following code:
public static class ListBoxMonitor
{
//holds the last item that was changed
//based on SelectionType chosen by user
private static ItemInfo lastItem = new ItemInfo();
//holds the previously selected list items
private static List<string> previousSelectedItemsList = new List<string>();
//create an enumeration
public enum SelectionType { Deselected, Either, Selected };
public static ItemInfo getLastItemChanged(System.Windows.Forms.ListBox lb, SelectionType sType)
{
List<string> currentSelectedItemsList = new List<string>();
//put selected items into a list
//so we can use list.Except
for (int i = 0; i < lb.SelectedItems.Count; i++)
{
currentSelectedItemsList.Add(lb.SelectedItems[i].ToString());
}//for
if (sType.Equals(SelectionType.Either))
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
}//if
else if (sType.Equals(SelectionType.Selected))
{
//get last item selected as a list
//by comparing the current list
//to the previous list
if (String.Compare(findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList).SelectionType, "Selected", true) == 0)
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
}//if
}//else if
else if (sType.Equals(SelectionType.Deselected))
{
//if item was deselected, switch the order
//compare previous list to current list
//if > 0, last item was de-selected
if (String.Compare(findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList).SelectionType, "Deselected", true) == 0)
{
lastItem = findExcludedItemInList(currentSelectedItemsList,
previousSelectedItemsList);
}//if
}//else if
//updated previousSelectedItems before returning
previousSelectedItemsList = currentSelectedItemsList;
return lastItem;
}//getLastItemChanged
private static ItemInfo findExcludedItemInList(List<string> list1, List<string> list2)
{
ItemInfo item = new ItemInfo();
//get list of items in list1 that aren't in list2
var lastItemList1 = list1.Except(list2).ToList();
if (lastItemList1.Count > 0)
{
//there should only be 1 item in the list
item.Name = lastItemList1[0].ToString();
item.SelectionType = "Selected";
}//if
else
{
//get list of items in list2 that aren't in list1
var lastItemList2 = list2.Except(list1).ToList();
if (lastItemList2.Count > 0)
{
//there should only be 1 item in the list
item.Name = lastItemList2[0].ToString();
item.SelectionType = "Deselected";
}//if
}//else
return item;
}//findExcludedItemInList
}//class
Usage:
public partial class Form1 : Form
{
ItemInfo lastItem = null;
public Form1()
{
InitializeComponent();
}
private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
//get only last selected item
//lastItem = ListBoxMonitor.getLastItemChanged(listBox1, ListBoxMonitor.SelectionType.Selected);
//get only last Deselected item
//lastItem = ListBoxMonitor.getLastItemChanged(listBox1, ListBoxMonitor.SelectionType.Deselected);
//get last changed item - Selected or Deselected
lastItem = ListBoxMonitor.getLastItemChanged(listBox1, ListBoxMonitor.SelectionType.Either);
}
}
I remembered that I can use CheckedBox instead.
Thanks all and I studied your code and learned new things.
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.