So every Page will live in memory as long as all ViewModels referenced by EventToCommands inside it stay alive.Now its commonplace for ViewModels to stay alive for a long time through an IoC or even being statically declared in App.xaml and so there we go.We found it!
Sounds easy and obvious now but it wasn’t so easy to locate.It took plenty of time fiddling around with the Windows Phone Performance Analysis Tool.Excellent tool.Could be better.Huge improvement compared to WinDbg 🙂

Ok so lets solve it.Whats the weakest link in that chain?

You guessed it its the CanExecuteChanged event.
The command does not need to reference EventToCommand.
This is where WeakEventListener comes in.Its not the purpose of this post to explain how WeakEvents and listeners work so go ahead and do some reading on the net to get you acquainted.

We know EventToCommand adds and removes an EventHandler to/from Command.CanExecuteChanged.What would be perfect is if EventToCommand itself added a WeakEventListener to the Command and solve this thing for us.UPDATE: Apparently MvvmLight is maybe trying to “solve” this issue in the next release but in a way that
totally doesn’t make sense to me.By using WeakActions inside of RelayCommand.I have opened a discussion on the issue here with detail explanation.

For those interested here’s one way of solving it inside EventToCommand that i found just playing around (without a lot of design and classes) :

Until that happens though lets hack our way around it cause that’s more fun shall we.
We know also we have to extend it but we do not have access unfortunately to any of its internals.We do have access though to the Command DP since it has to be public.What could we do?
How about replacing (behind the scenes) the original Command with our own Wrapper (Adapter) Command?
Lets call it WeakCommand.It will internally hold on to the original command but this time we will listen to it using a WeakEventListener. WeakCommand will of course itself be an ICommand which will just delegate all calls to and from the original.Nice.Seems that might do the trick.
So how do we “replace” the original command that ETC gets data bound to? We need to listen to it for changes and when it changes we will update it by calling
ETC.Command = new WeakCommand(ETC.Command);

NOTE: This will remove the ViewModel-Command Binding! If for some reason you change your Command from within your ViewModel and expect it to rebind this won’t happen.
That’s an uncommon case though.This might be solvable as well but not sure yet.Am thinking something along the lines of grabbing the original BindingExpression (and therefore the Binding object) from the Command DP and apply that to BindingListener.Will look into that as well.

This will call ETC’s code to unhook from the Original command (what we wanted) and then immediatelly hook onto our own WeakCommand.
How do we listen for Dependency Property changes when there is no event though?
Easy.We’ll make a BindingListener class with one generic DependencyProperty of type Object and bind that to the Command DP of ETC.This way when ETC.Command changes that surrogate is gonna notify us so we know to replace the command.The binding surrogate is not at all new btw.It’s probably as old as Silverlight.
Hmm.Sounds good but will that work? Of course it will.Would i be making this post if it didnt? 😛

Ok.So what did we try to do.The idea is that since EventToCommand never unhooks from the event
(Dont be fooled by the Detach method.This is called when the Trigger is removed from the TriggerCollection) a good time to unhook it is probably when the element is removed from the visual tree.Either it was defined in a DataTemplate and the collection binding changed so everything gets refreshed or the user left the Page containing it.Pretty safe.Well not exactly.You have to account for the cases where the same element for some reason gets removed and re-added. That is why, after removing the Command to avoid the leak, we keep a reference to it in case it gets re-added in which case we re-apply.Seems to work nicely but you need to keep these in mind :

The Binding gets removed when you set Command = null (same as BindingOperations.ClearBinding() in WPF). If you don’t change the Command from inside the VM ,which i expect you don’t, then it shouldn’t be a problem.

You have to know for sure that the element you are attaching to fires Loaded/Unloaded events as expected! I noticed a case with a BindableApplicationBar wrapper that this did not happen.