Reputation: 207
I have a ListBox which has its DataSource set to a BindingList.
BindingList<PairDiff> pairList = new BindingList<PairDiff>();
pairList.RaiseListChangedEvents = true;
listBox1.DataSource = pairList;
The type of the BindingList implements and raises the INotifyPropertyChanged
when one of its members is updated.
Still the ListBox does not update it's display when some data in an existing item is changed. Only when an item is changed or removed.
When I debug into the listBox.Items collection, the new data is there. It is just not displayed!
What is displayed in the ListBox is the PairDiffs ToString
method.
edit:
public class PairDiff : INotifyPropertyChanged
{
public Pair pair;
public double diff;
public event PropertyChangedEventHandler PropertyChanged;
public void UpdateDiff(double d) // this is called to update the data in the list
{
diff = d;
PropertyChanged(this, new PropertyChangedEventArgs("diff"));
}
public override string ToString() // this is displayed in the list
{
return pair + " " + diff;
}
}
to update the data in the listbox:
public void UpdateData(Pair pair, double d)
{
var pd = pairList.First((x) => x.pair == pair);
pd.UpdateDiff( d );
}
Upvotes: 3
Views: 2550
Reputation: 207
FWIW i finally found the issue and its that typical winforms threading thing:
putting the update of my listbox in a InvokeRequired block solves it:
public void UpdateData(Pair pair, double d)
{
Action action = () =>
{
var pd = pairList.First((x) => x.pair == pair);
pd.UpdateDiff(d);
};
if (listBox1.InvokeRequired)
{
listBox1.Invoke(action);
}
else
{
action();
}
}
Upvotes: 0
Reputation: 3979
The problem is that the Listbox is caching it's values. The easiest solution is to catch the ListChanged-Event and redraw your Listbox in it:
private void Items_ListChanged(object sender, ListChangedEventArgs e)
{
listbox.Invalidate(); //Force the control to redraw when any elements change
}
I refer to this article.
Upvotes: 1