0

The ListBox has children that have subscriptions. Let's say ListBox has StackPanel and StackPanel has a Button that has a subscription.

After using StackPanel, I want to remove StackPanel from the ListBox.

// There is a ListBox named "list".

StackPanel stack = new StackPanel();
Button button = new Button();

RoutedEventHandler eventHandler = (s, e) => { ... };
button.Click += eventHandler;

stack.Children.Add(button);
list.Items.Add(stack);

...

// Now I want to remove StackPanel. 
// Should I do this before removing: "button.Click -= eventHandler;"?

list.Items.Remove(stack);

Should I unsubscribe Button before removing StackPanel from the ListBox (to avoid memory leaks)? Or is it enough to remove StackPanel from the ListBox so that the child subscriptions (in this case, Button) disappear and the garbage collector can easily collect them? Thank you.

  • Even if you're not going to go the full MVVM route, you should look at DataTemplates and Commands - that way you won't have to worry about unsubscribing from events. – Peregrine Jan 03 '21 at 09:46
  • 1
    When a longer lived instance registers to an event, you should unsubscribe it to get it detached. – Jeroen van Langen Jan 03 '21 at 11:07
  • Do I understand correctly that when you remove a StackPanel from the list, the child elements are removed first (the button in this case)? That is, I don't have to worry about unsubscribing the button, since it gets removed before the StackPanel? – Кирилл Зацепин Jan 03 '21 at 11:22
  • What class defines the eventhandler? Assuming that's part of a (longer lived) window, then you need to unregister the event, otherwise you'll get a memory leak as the garbage collector won't collect the button. This code construct still looks more like what I was writing in winforms in 2005, rather than how you should be using WPF. – Peregrine Jan 03 '21 at 11:36
  • 1
    You could unsubscribe your event handler or use a weak event pattern instead. – Andy Jan 03 '21 at 12:42
  • Binding and commands avoid memory leaks. You could use a weak reference for a routed event https://stackoverflow.com/questions/18565396/using-wpf-4-5-generic-weak-event-manager-for-handled-routed-events But pretty much all commercial teams use command binding. – Andy Jan 03 '21 at 12:45
  • @JeroenvanLangen: _"When a longer lived instance registers to an event, you should unsubscribe it to get it detached"_ -- that is the opposite of correct. An object's lifetime is defined by whether it's "reachable". An object that is "shorter lived" is one that becomes unreachable before another. If that object publishes an event and other objects subscribe to that event, those other objects do not need to unsubscribe to the shorter-lived object, because it's unreachable, and so any references it has to other objects also cannot be reached via the shorter-lived object. – Peter Duniho Jan 04 '21 at 18:50

1 Answers1

0

As far as I am aware

list.Items.Remove(stack);

is not going to modify the contents of the StackPanel at all. You could continue to use the object referenced by stack normally afterwards.

I would probably remove the controls first, and then unsubscribe the event(s). This way the control will function normally up to the very last moment when it is removed. If you did it the other way around it might be fine, but there is a small chance that the user clicks the button just after the event was removed, and obviously then the button doesn't work.


Its also worth mentioning that you don't absolutely have to unsubscribe the events at all. This can be a good practice, but also could just be adding unnecessary complexity. For a small application it probably won't cause any harm to leave them. Ultimately the garbage collector will clean up all these objects, once nothing is using them anymore. (Say, after the WPF window is closed).

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
  • If there was no event handler, the StackPanel and all it's contents including the Button would eventually get garbage collected though - assuming that there is no other external reference to any of the controls. – Peregrine Jan 04 '21 at 17:57
  • @Peregrine I agree, but it depends what will happen next in the program, which the question doesn't specify. I think the OP was unsure what effect that adding/removing child items would have and how that relates to events. I didn't think they were asking about GC. – StayOnTarget Jan 04 '21 at 17:59
  • Even if the memory hit is tiny, you don't want to leave uncollected items laying around in a long-running application. – Peregrine Jan 04 '21 at 18:11