0

I have an attached behavior that used on a listbox, it should automatically select the first element in the list, if the list contains only one element.

The only way that I have found to hook the listbox when the list changes, is to use the listbox' itemcollections CollectionChanged event:

private static void ListenToItemsCollectionChange(ListBox listBox)
{
    var collection = (INotifyCollectionChanged)listBox.Items;

    collection.CollectionChanged += (sender, args) => SelectAndSetFocusToFirstElement(listBox);
}

The problem now, is that there is no way of unsubscribing from the event, which potentially leads to multiple invokations of SelectAndSetFocusToFirstelement( ).

The normal solution to this, is to not use lambdas. But then I would loose my listbox, which I need for selecting the first element.

Any suggestions on how this can be solved?

Full code

Vegar
  • 12,828
  • 16
  • 85
  • 151

2 Answers2

2

A Lambda is just a shortcut for a delegate, so you can rewrite the lambda as

NotifyCollectionChangedEventArgs collectionChangedDelegate = (sender, arg) =>
{SelectAndSetFocusToFirstElement(listBox)};

then you can add to the collection changed event

collection.CollectionChanged += collectionChangedDelegate

and remove

collection.CollectionChanged -= collectionChangedDelegate
MarcE
  • 3,586
  • 1
  • 23
  • 27
  • But where do you keep the reference to collectionChangedDelegate between calls to `ListenToItemsCollectionChange`? – Vegar Jun 27 '11 at 11:12
  • When I've done stuff like that before I've used a class level dictionary to hold references to various delegates and added a handler to the Unloaded event of the control to remove the event delegate (and it's associated reference in the dictionary) – MarcE Jun 27 '11 at 11:23
0

I got a little bit confused what do You meand by "But then I would loose my listbox" ?

Maybe this solution will be sufficient

You could keep the event handler in temporary variable like that

  EventHandler handler = (a, b) => { }; // You must use aproperiate delegate
    collection.CollectionChanged += handler

and if You want to unsubscribe You could use -= handler

Berial
  • 557
  • 1
  • 8
  • 23
  • The eventhandler for CollectionChanged gives you no reference to the listbox - only the collection. By using lambda, you still have access to local variables, and can there for access the listbox passed as parameter to the `ListenToItemsCollectionChage()`-method. – Vegar Jun 27 '11 at 11:10
  • And how would you use an reference to an event handler stored in a temporary variable from another place in time? – Vegar Jun 27 '11 at 11:14