Totally stumped by something that seems easy, and has been done to death... Yet still stumped.
What I want to do: I've got a WinForms ListBox. Its items are populated with objects, the DisplayMember is set. As the app runs, the data in the listed items might change, including the field behind the DisplayMember. I want the text displayed in the ListBox to change when this happens, and I also want the ListBox to re-sort itself so the items remain in alphabetical order.
A BindingList works fine to update the displayed text when the data changes, but for the life of me, I can't get it to sort.
I reviewed this: http://msdn.microsoft.com/en-us/library/ms993236.aspx
Plus numerous threads here about how to do this, but none of it seems to work for a ListBox.
Setting the Sorted property on the ListBox is similarly unhelpful.
What do I need to do to get a ListBox to sort itself?
You can use a BindingSource object. Just drag-n-drop it into your form and point your ListBox.DataSource property to this BindingSource object. Then go to the BindingSource's properties and define Sort as you need.
Then in code you can set myBindingSource.DataSource = myCollection
and voila, your listbox is populated and sorted.
Easy.
As with Patrol02's post, however you may want to try setting the DataSource to null and then reassigning it based on an event triggered by the list size changing. You could use the observer pattern on the collection, overriding the Add and Remove methods to notify watchers to rebind themselves.
Resetting the DataSource will effectively sort the ListBox:
listBox1.DataSource = null;
listBox1.DataSource = myBindingList;
listBox1.DisplayMember = "MyField";
But that's not automatic. As I understand, sorting should happen whenever the field behind the DisplayMember is updated, through an event or something like that...
See my complete test anyway:
public partial class Form1 : Form
{
public BindingList<ABC> myBindingList = new BindingList<ABC>();
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
myBindingList.Add(new ABC("zzz"));
myBindingList.Add(new ABC("aaa"));
}
private void button2_Click(object sender, EventArgs e) {
myBindingList[0].MyField = "ccc"; // was "zzz"
myBindingList[1].MyField = "ddd"; // was "aaa"
listBox1.DataSource = null;
listBox1.DataSource = myBindingList;
listBox1.DisplayMember = "MyField";
}
private void Form1_Load(object sender, EventArgs e) {
listBox1.DataSource = myBindingList;
listBox1.DisplayMember = "MyField";
}
}
public class ABC {
public string MyField { get; set; }
public ABC(string val) {
MyField = val;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With