WinRT in C++/Cx and registering and unregistering event handlers

Having to work in C++/Cx, every day I have new appreciation for C#. Things that I take for granted in C#, well, they are not straightforward C++. Take the example of event handlers.

In C#, the usual way of registering and unregistering event handlers is pretty straight forward:

e.g. Click += Button_click_handler and Click -= Button_click_handler

I tried to do the same in C++/Cx and got a nasty shock. That is not how it works! It took quite a bit of searching and finally I reached this MSDN page:

http://msdn.microsoft.com/en-us/library/windows/apps/Hh758286.aspx

The MSDN page, neatly sums it up:

If you need to remove an event handler in C++/CX, you’ll need a registration token, which you should’ve received from the return value of the += event handler registration. That’s because the value you use for the right side of the -= deregistration in the C++/CX syntax is the token, not the method name. For C++/CX, you can’t remove handlers that were added as a XAML attribute because the C++/CX generated code doesn’t save a token.

I could not really find any code samples in 15 minutes of searching, so by trial and error, this is what I figured out

The event registration call returns a token. You need this token to later de-register, so better save it, else you will not be able to deregister. If you declared your event handler in XAML, well, forget about deregistration. You need the token, so if you really want the ability to deregister the event handler, you will have to move the event handler registration from XAML to code behind.

This is how ended up writing the code (I was writing an event handler for the LoadCompleted event in WebView):

In the header file for the WinRT XAML control:

1
Windows::Foundation::EventRegistrationToken myEventHandlerRegistrationToken;

In the C++ code behind file, to register the event handler:

1
2
3
4
5
myEventHandlerRegistrationToken = this->myWebView->LoadCompleted += ref new LoadCompletedEventHandler(this, &MyUserControl::myWebView_LoadCompleted);

void MyUserControl::myWebView_LoadCompleted(Platform::Object^ sender, Windows::UI::Xaml::Navigation::NavigationEventArgs^ e)
{
}

And then to unregister the event handler:

1
this->myWebView->LoadCompleted -= myEventHandlerRegistrationToken;