How to sort a listBox in C#? - c#

I have typed numbers in a textbox and added them into a listBox. Now I need to order that listbox. This is my try:
int[] array = listBox1.Items.Cast<int>().ToArray<int>();
Array.Sort(array);
listBox1.Items.Clear();
foreach (int item in array)
{
listBox1.Items.Add(item);
}
It throws an 'System.InvalidCastException'. But I can't figure it out HOW to solve it.

You can use a lambda
var array = listBox1.Items.OfType<string>().Select(x => int.Parse(x))
.ToArray();

First, I want to say that it is not a good idea to store data inside a control. Always put your data inside types that can handle them like a List, Dictionary, etc. and then bind that to your listbox object. I guess you are working on windows forms. Then add a property to your form and put all your data in it.
something like this
public partial class Form1 : Form
{
List<string> _items = new List<string>(); // <-- Add this
public Form1()
{
InitializeComponent();
_items.Add("One"); // <-- Add these
_items.Add("Two");
_items.Add("Three");
listBox1.DataSource = _items;
}
public void add()
{
_items.Add("four");
_items.Sort();
}
}

This is as simple as
listBox1.Sorted = true;
UPDATE
var array = new object[listBox1.Items.Count];
listBox1.Items.CopyTo(array, 0);
listBox1.Items.Clear();
var sortedArray = array.Select(n => (object)Convert.ToInt32(n)).OrderBy(n => n).ToArray();
listBox1.Items.AddRange(sortedArray);

ListBox items can cast to string. So, You must cast it to string[], then convert to int[], then sort it and finally add sorted data to ListBox.
string[] strArray = listBox1.Items.Cast<string>().ToArray();
int[] intArray = strArray.Select(x => int.Parse(x)).ToArray();
Array.Sort(intArray);
listBox1.Items.Clear();
foreach (int item in intArray)
{
listBox1.Items.Add(item);
}
I hope this will be useful.

Related

c# - Splitting a string, then writing into datagridview rows

I have a serialport which reads a string such as: "11,22,33,44", however the number of separators differ etc: "11,22,33,44,55,66"
I want to split the string and then write the separated strings into a datagridview, I have tried:
string[] array = _text.Split(',');
table.Rows.Add(array[0], array[1], array[2], array[3]);
datagridview1.DataSource = table;
However, the problem here is that the arrays may come in a different amount.
Is there a way to do this?
Thanks for any help
You don't have to add each item as a parameter to Add. The Add method takes an array as the parameter, so you can just do:
string[] array = _text.Split(',');
table.Rows.Add(array);
datagridview1.DataSource = table;
And it will add columns corresponding to the number of items in your array.
If you want to add multiple rows with a varying number of columns, you will need to check the size of the array first, then add columns to the DataTable as necessary, otherwise you will get an exception if the number of items in the array exceeds the number of columns in the DataTable.
All you need to do is iterate over array and add each item.
string[] array = _text.Split(',');
foreach(var item in array)
{
table.Rows.Add(item);
}
datagridview1.DataSource = table;
For do this you can parse into string list..
_text = "11,22,33,44,55,66";
List<String> str_list = new List<String>();
str_list = _text.Split(',').ToList();
foreach(var item in str_list)
{
table.Rows.Add(item);
}
datagridview1.DataSource = table;
This will work for you..
You can directly add the array as the row to the DataGridView, check the below code snippet.
namespace SO
{
using System;
using System.Windows.Forms;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
var input = "11,22,33,44";
string[] array = input.Split(',');
dataGridView1.Rows.Add(array);
}
}
}

Populating listview with List<List<string>>

I'm coding in C# andI have a listview control with few columns, and I'm wondering, how can I add items to it from List<List<string>>. I am able to add items with
var item3 = new ListViewItem(new[] { table[0][0], table[0][1], table[0][2], table[0][3], table[0][5], table[0][7], table[0][8] });
but that doesn't seem right to me, and neither it would work because the amount of Lists is random.
You can use List<T>.ToArray to convert the list into an array which you then pass to the constructor of ListViewItem. As you are only interested in the first subitem of your table, you can just do it like this:
var item3 = new ListViewItem(table[0].ToArray());
You can use the following code to fill all the List<List<string>> into your ListView:
listView1.Items.AddRange(table.Select(list=>new ListViewItem(list.ToArray())))
.ToArray();
probably you mean like this ?
sample data
item1
List<string> list1 = new List<string>();
list1.Add("item-1.1");
list1.Add("item-1.2");
item2
List<string> list2 = new List<string>();
list2.Add("item-2.1");
list2.Add("item-2.2");
allitem
List<List<string>> listAll = new List<List<string>>();
listAll.Add(list1);
listAll.Add(list2);
string value
string sResult = string.Join(", ", from list in listAll from item in list select item);
list value
List<string> lResult = new List<string>(from list in listAll from item in list select item);
binding
lv.DataSource = lResult;
lv.DataBind();
result
item-1.1 item-1.2 item-2.1 item-2.2

How to select all items in a Listbox and concatenate them in ASP.NET C# Webform?

Right now I have
String myString = listbox1.Text.ToString();
However this only returns only the 1st item, even if I hit ctrl and select all of them.
Thanks for any help
Using an extension method, you can do this:
public static class Extensions
{
public static IEnumerable<ListItem> GetSelectedItems(this ListItemCollection items)
{
return items.OfType<ListItem>().Where(item => item.Selected);
}
}
Usage:
var selected = listbox1.Items.GetSelectedItems();
Now you can take the IEnumerable<ListItem> and convert that to a string array, then finally make it into a single string separated by semicolons, like this:
// Create list to hold the text of each list item
var selectedItemsList = new List<string>();
// Create list to hold the text of each list item
var selectedItemsList = selected.Select(listItem => listItem.Text).ToList();
// Build a string separated by comma
string selectedItemsSeparatedByComma = String.Join(",",
selectedItemsList.ToArray());
You are right, WebForms ListBox doesn't have the SelectedItems property. However, you can do
listBox.Items.OfType<ListItem>().Where(i => i.Selected);
That will give you the items you are looking for.
If you can't use LINQ, just do a foreach over listBox.Items, and do whatever you want when the item is Selected.

How to select a string entry in a listbox by a given string without looping?

In WPF there's no listbox.findString.
Let's say we have a listbox:
ListBox b = new ListBox();
Then you could use LINQ:
int index = b.Items.IndexOf((
from ListBoxItem a in b.Items
where a.Content.ToString() == "something"
select a).First());
Or you can use foreach:
foreach (ListBoxItem lbi in b.Items)
{
if (lbi.Content is string && (string)lbi.Content == "something")
{
index = b.Items.IndexOf(lbi);
break;
}
}
var entries = listBox.Items.Where(item => item.ToString() == "something");
In most scenarios, you want to bind the ListBox's ItemsSource to an actual collection in your code that implements IEnumerable, then use the .Where().First() statement to find the first occurence of your string, like this:
List<string> lstb = new List<string>() { "StringA", "StringB", "StringC" };
string stringC = lstb.Where(s => s == "StringC").First();
Then if you want to programmatically select the item in your list:
yourListBox.SelectedItem = stringC;
However I strongly suggest you take the time to learn about databinding and the MVVM model which simplifies interaction with WPF controls by a lot.

Cannot convert SelectedObjectCollection to ObjectCollection ?

I am trying to get a list of all elements from ListBox if no or one of items is selected or list of selected items if more than 1 are selected. I have written such a code but it doesn't compile :
ListBox.ObjectCollection listBoXElemetsCollection;
//loading of all/selected XMLs to the XPathDocList
if (listBoxXmlFilesReference.SelectedIndices.Count < 2)
{
listBoXElemetsCollection = new ListBox.ObjectCollection(listBoxXmlFilesReference);
}
else
{
listBoXElemetsCollection = new ListBox.SelectedObjectCollection(listBoxXmlFilesReference);
}
So for this piece of code to work I would need to use something like ListBox.SelectedObjectCollection listBoxSelectedElementsCollection; which I do not want because I would like to use it in such an foreach:
foreach (string fileName in listBoXElemetsCollection)
{
//...
}
I'd simply this a bit and not mess with the ListBox ObjectCollections if you don't need to. Since you want to iterate items on your ListBox as strings, why not use a List and load the list how you show:
List<string> listItems;
if (listBoxXmlFilesReference.SelectedIndices.Count < 2) {
listItems = listBoxXmlFilesReference.Items.Cast<string>().ToList();
} else {
listItems = listBoxXmlFilesReference.SelectedItems.Cast<string>().ToList();
}
foreach (string filename in listItems) {
// ..
}
You need to convert SelectedObjectCollection to an array of object[].
ListBox.SelectedObjectCollection sel = new
ListBox.SelectedObjectCollection(listBoxXmlFilesReference);
ListBox.ObjectCollection col = new
ListBox.ObjectCollection(listBoxXmlFilesReference,
sel.OfType<object>().ToArray());
I can see what you're trying to do and it doesnt compile because the type ListBox.ObjectCollection is not the same as ListBox.SelectedObjectCollection - even though in your case they are lists that contain strings the classes themselves are different hence the compile error.
Assuming your items are strings in the listbox you could do:
var items = listBoXElemetsCollection.Items.OfType<string>();
if (listBoXElemetsCollection .SelectedIndices.Count >= 2)
items = listBoXElemetsCollection.SelectedItems.OfType<string>();
foreach(var item in items)
//do stuff

Categories

Resources