Cannot retrieve multiple values from a listbox c# - c#

I am populating a listBox at runtime from a database as follows:
List<FILE_REPORT_TYPES> ReportTypes = GetReportTypesFromDatabase(ReportMappingIds)
BindingList<FILE_REPORT_TYPES> pbReportTypesBindingList = new BindingList<FILE_REPORT_TYPES>(ReportTypes);
listBoxReports.DataSource = ReportTypesBindingList;
listBoxReports.DisplayMember = "REPORT_DESCRIPTION";
listBoxReports.ValueMember = "REPORT_ID";
I then would like select multiple items on the listBox when running the windows form and retrieve each individual Value of my selections. If only one selection is made one could do the following:
listBoxReports.SelectedValue;
I would like to do the following:
var list = listBoxReports.SelectedValues;
However this is not allowed i.e. "SelectedValues" does not exist.
Some people are erroneously suggesting that in this particular case SelectedIndices may be used. It cannot be used, I am trying to retrieve the "VALUE". This cannot be done (in this particular case):
listBox.Items[i].Value;
I think the solution should be along the lines of:
foreach(var line in listBox.Items)
{
var res= ((SOME CASTING)line).Value;
}

To get the selected items you have 2 options
a.) ListBox.SelectedIndices which returns the indices of the selected items which you then need to use to look up in the Items property what the value is or
b.) ListBox.SelectedItems which returns you a collection with the selected items themselves (be aware that it is an objectlist so you need to transform the items into your appropriate datatype).
Edit: With the additional information the following is possible
List<FILE_REPORT_TYPES> mySelectedList = new List<FILE_REPORT_TYPES>();
foreach (Object selectedItem in ListBox.SelectedItems)
{
mySelectedList.Add( ((FILE_REPORT_TYPES)selectedItem) );
}

You can use ListBox.SelectedIndices or ListBox.SelectedItems.
If you want to get all selected-items, you can let the foreach cast:
foreach(FILE_REPORT_TYPES frt in listBox.SelectedItems)
{
// ...
}
or if you want to get the ReportID into a list with the help of LINQ:
List<decimal> reportIds = listBox.SelectedItems.Cast<FILE_REPORT_TYPES>()
.Select(frt => frt.REPORT_ID)
.ToList();

Alternative to the selected value you could do the following
listBoxReports.SelectedItems;

Answer (the casting is the trick):
List<decimal> reportIds = new List<decimal>();
foreach(var line in listBoxReports.SelectedItems)
{
reportIds.Add(((PB_FILE_REPORT_TYPES)line).REPORT_ID);
}

You may try like below
List<FILE_REPORT_TYPES> reportList = new List<FILE_REPORT_TYPES>();
foreach(var item in listBox.SelectedItems)
{
reportList.Add((FILE_REPORT_TYPES)item);
}

Related

C# delete tagged Object

I have a question regarding use of "Tag" :
I have a ListBox, or ListView, in which I have the name of my objects, I addes a "Tag" property to find its corresponding object :
foreach(Operation op_ass in ListOpAss1)
{
op_ass.getNom(Properties.Settings.Default.Langue);
ListViewItem item = new ListViewItem(op_ass.Nom);
item.Tag = op_ass;
listBoxAss1.Items.Add(op_ass.Nom);
}
Now what I would like, is when I select an item in my list(or several), make an action on corresponding objects. But how can I find them back?
For example I want to remove selected objects from a List, or get the list of Operation ID (without displaying ID in my list).
Looks like you are adding the property, op_ass.Nom into the listbox instead of the ListViewItem, item. Modify your code as follows:
foreach (Operation op_ass in ListOpAss1)
{
op_ass.getNom(Properties.Settings.Default.Langue);
ListViewItem item = new ListViewItem(op_ass.Nom);
item.Tag = op_ass;
// Add the list view item instead of op_ass.Nom
listBoxAss1.Items.Add(item);
}
Now you should be able to retrieve the tag from selected item/items as follows:
var operation = ((listBox1.SelectedItem as ListViewItem).Tag) as Operation;
Alternatively, you could think of using data binding as follows:
foreach (Operation op_ass in ListOpAss1)
{
op_ass.getNom(Properties.Settings.Default.Langue);
}
listBoxAss1.DataSource = ListOpAss1;
listBoxAss1.DisplayMember = "Nom";
And access the data bound object as follows:
var operation = listBox1.SelectedItem as Operation;
using foreach is kind of deprecated you can look into implemented functions in list of objects
ListOpAss1.ForEach(x=>
{
x.getNom(Properties.Settings.Default.Langue);
var item = new ListViewItem(x.Nom);
item.Tag = x;
listBoxAss1.Items.Add(x.Nom);
});
in order to select an item in a list you can use SingleOrDefalt() or Skip(count) take (count) for multiple files or you can run native querys with conditions to search the list like this
var items = collection.Where(x=> x.City == "Burgas").ToList(); //You can use select if you want only certain properties of the object to be selected
///then you can use that new item list to remove the objects from the collection list like this
items.ForEach(x=>
{
collection.Remove(x);
});

How to retrieve selected values for selected items in a ListBox?

I'm populating a ListBox in a WinForms application, this way:
listBoxUsers.DataSource = ctx.Users.ToList();
listBoxUsers.DisplayMember = "Name";
listBoxUsers.ValueMember = "Id";
how to retrieve the selected Ids when I'm setting the SelectionMode to MultiSimple
I want to do a foreach loop on them, like this:
foreach(var itemId in listBoxUsers.SelectedValues)//unfortunately not exist
{
int id = int.Parse(itemId);
// . . .
}
Since you know the type of items, you can use such code:
var selectedValues = listBox1.SelectedItems.Cast<User>().Select(x=>x.Id).ToList();
Side Note: The ListBox control lacks a GetItemValue method. A method which should work like GetItemText, but for getting values. In the linked post I shared an extension method to get the value from an item. Using that extension method you can get selected values independent from type of items:
var selectedValues = listBox1.SelectedItems.Cast<object>()
.Select(x => listBox1.GetItemValue(x)).ToList();
If for some reason you are interested to have a text representation for selected values:
var txt = string.Join(",", selectedValues);
Have you tried with the SelectedItems property?
foreach (var item in listBoxUsers.SelectedItems)
{
}
try this:
foreach (DataRowView item in listBoxUsers.SelectedItems)
{
int id=int.parse(item[0].ToString());
}

How to remove an Item from a combobox when a datasource is assigned to an enum?

How to remove an Item from a combobox when a datasource is assigned to an enum?
When trying to remove by Items.Remove, got error:
Items collection cannot be modified when the DataSource property is set.
Any suggestion?
Note: I would keep using the enum because I deal it in many places in the code.
The code:
public enum DefaultValueType
{
None = 0,
Static = 1,
Query = 2
}
cBoxDefaultType.DataSource = Enum.GetValues(typeof(DefaultValueType));
In one case, I want to remove the Query item from the options of the combobox.
cBoxDefaultType.Items.RemoveAt(2); // Throw exception
I found the solution by filtering the array of Enumeration:
Enum.GetValues(typeof(DefaultValueType))
.Cast<DefaultValueType>()
.Where(p => p != DefaultValueType.Query)
.ToArray<DefaultValueType>()
You need to remove item from DataSource and rebind or use just .Items withoutDataSource
In your case you need to convert Enum to array and then work with it.
Also for .NET 2.0 (Remove 'Invalid' item from enum 'SomeEnum'):
comboBox1.DataSource = Array.FindAll((SomeEnum[])Enum.GetValues(typeof(SomeEnum)),
(SomeEnum SM) => { return SM != SomeEnum.Invalid; });

How to check if an item exists in more than one listbox? ASP.NET/C#

I have three sets of listboxes, I move items from lb1 to lb2, from lb3 to lb4 and from lb5 to lb6. The listboxes on the left contains the same items and I don't want the user to be able to submit the page if one or more items from the left listboxes is added to more than one listbox to the right. For example, item A in lb1, lb3 and lb5 can only be saved in either lb2, lb4 or lb6, not in two or three of them.
I want to perform this check before submitting the page (and later on I will add validation with javascript) and I wonder what is the most efficient way to do this.
Add all items to a list and check if there are any duplicates?
Thanks in advance.
Edit:
something like this:
List<string> groupList = new List<string>();
foreach (ListItem item in lbFullAccess.Items)
{
groupList.Add(item.Value.ToString());
}
foreach (ListItem item in lbContributor.Items)
{
groupList.Add(item.Value.ToString());
}
foreach (ListItem item in lblReadOnly.Items)
{
groupList.Add(item.Value.ToString());
}
Well, there's a hundred different ways you could do it. Absolutely nothing wrong with your suggestion of iteration.
You could have a little fun with LINQ:
public bool AreAllValuesUnique()
{
// Build up a linq expression of all of the ListItems
// by concatenating each sequence
var allItems = lbFullAccess.Items.Cast<ListItem>()
.Concat(lbContributor.Items.Cast<ListItem>())
.Concat(lbReadOnly.Items.Cast<ListItem>());
// Group the previous linq expression by value (so they will be in groups of "A", "B", etc)
var groupedByValue = allItems.GroupBy(i => i.Value);
// Finally, return that all groups must have a count of only one element
// So each value can only appear once
return groupedByValue.All(g => g.Count() == 1);
}
Not really sure about the performance of calling Cast (converting each element of the ListItemCollection to a ListItem, resulting in an IEnumerable) on each collection, but it is probably negligible.

WebForms Passing CheckboxList Values To List<T>

I have a GridView which I have a List bound to - I want to be able to allow filter of the data based on multiple CheckBoxLists.
For arguments sake let's say I have a List of Jobs, and I want to filter the jobs by code - So I would have a CheckBoxList like
C#
ASP.NET
php
F#
etc..
If someone selects multiple codes, how do you pass the values into a List to rebind to the GridView? Is there a way to pass values as an array? Or maybe a comma seperated string?
Any examples (I'm a C# boy) would be greatly appreciated, and I hope I have explained it properly :S
use an ObservableCollection<T> . it automatically allows the gridview to "observe" that the underlying datasource has changed and thus update itself.
wherever you do your filtering for the gridview you have to build the list manually before you filter.
var languages = new List<string>();
foreach (ListItem item in cblLanguages.Items)
{
if (item.Selected)
{
languages.Add(item.Value);
}
}
then when you filter you can do something like (example using linq2sql)
var jobs = db.Jobs.Where(x => langauges.Contains(x.LanguageCode));
gvJobs.DataSource = jobs;
gvJobs.DataBind();
I'm not sure I completely understand your question. But I often do the following to get ListItems into a form queryable via LINQ to objects:
var items = cblLanguages.Items.Cast<ListItem>();
// Selected Items
var selectedItems = items.Where(li => li.Selected);
// Item's containing 'C'
var itemsWithC = items.Where(li => li.Text.Contains("C"));
// Values between 2 and 5
var itemsBetween2And5 = from li in items
let v = Convert.ToInt32(li.Value)
where 2 <= v && v <= 5
select li;

Categories

Resources