I am developing a custom control, which internally subscribes to Touch.FrameReported - a static event. This has the potential to cause a memory leak (and in some case, it do
tl;dr If you use a combination of #1 (unsubscribe on unload) and #3 (weak event listener), then I don't think that your control should be at fault for any memory leaks. There is nothing more you can do.
Implementing IDisposable
doesn't really help, because no-one wants to call "Dispose" on UI elements, and anyway, in those instances where "Unloaded" isn't getting called, requiring "Dispose" would just kick the can down the road. And you're right, the finalizer would not be called if there is a static event holding on to your control as part of its invocation list.
My understanding is that "Unloaded" should be called when your control is removed from the Visual Tree. So in cases where "Unloaded" is not triggered where it definitely should have been, then either there is a bug in a framework control somewhere (which does seem to be a possibility), or there is a bug in your users' code that is preventing your control's container from being unloaded. In either case, your control would not be the source of the memory leak.
Using a weak event handler is probably a good fail-safe -- it allows your control to be GC'd if the only references to it are weak event listeners (hence, this would prevent your "FrameReported" listener from causing a memory leak). I understand your point about implementations -- it seems very tricky to implement, but there is nothing wrong with the technique in principle (as you probably know, the framework uses it as the event listener for bindings).