Custom Collection Item Swap with ListBox DataSource problem

A

Andreas Zita

Hello!

I have a Custom Collection which is set as datasource to a ListBox. A Form
enables moving items up and down in the list. In the collection this is
implemented like this:

public void Swap(int oldIndex, int newIndex)
{
if (newIndex >= 0 && newIndex < List.Count && newIndex != oldIndex)
{
object tmp = List[newIndex];
List[newIndex] = List[oldIndex];
List[oldIndex] = tmp;
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved,
newIndex, oldIndex));
}
}

What happens now is that the listbox automatically switches positions of the
items and selects the new index (as should). The problem is that when the
event SelectedIndexChanged for the ListBox is triggered (automatically), the
SelectedItem is still the old item! How is this possible? Does the ListBox
select a new index before refreshing its datasource? ...

/AZ
 
B

Bart Mermuys

Hi,

Andreas Zita said:
Hello!

I have a Custom Collection which is set as datasource to a ListBox. A Form
enables moving items up and down in the list. In the collection this is
implemented like this:

public void Swap(int oldIndex, int newIndex)
{
if (newIndex >= 0 && newIndex < List.Count && newIndex != oldIndex)
{
object tmp = List[newIndex];
List[newIndex] = List[oldIndex];
List[oldIndex] = tmp;
OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved,
newIndex, oldIndex));
}
}

What happens now is that the listbox automatically switches positions of
the items and selects the new index (as should). The problem is that when
the event SelectedIndexChanged for the ListBox is triggered
(automatically), the SelectedItem is still the old item! How is this
possible? Does the ListBox select a new index before refreshing its
datasource? ...

That is exactly what is happening, unfortunately.

The events go like this:
CustomCollection -> CurrencyManager -> ListBox

So, when your custom collection invokes an ItemMoved event, the
CurrencyManager translates this into a position-changed-event and an
item-reset-event, in this order.

The ListBox responds to the position-changed-event, changes its selection
and fires IndexChanged, but at that time, ListBox.List contains a cached
array of the objects and so SelectedItem returns the wrong object.

Then the ListBox responds to the item-reset-event, the cached array is
updaded and the items appear in the expected order.


One workaroud (which only works if ListBox.Sort is false), would be to use
the CurrencyManager.CurrentChanged event instead of the
ListBox.SelectedIndexChanged event, eg. :

listBox1.DataSource = customCollection;
listBox1.DisplayMember = "...";

listBox1.BindingContext[ customCollection ].CurrentChanged+=
new EventHandler(OnCurrentChanged);

private void OnCurrentChanged( object sender, EventArgs e )
{.
CustomObject co = (CustomObject)listBox1.BindingContext[
customCollection ].Current;
}


HTH,
Greetings
 
A

Andreas Zita

Ahh thanks for helping me understand this! Using CurrentChanged works for
now ...

/AZ
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top