I'm trying to add an overload to my INotifyPropertyChanged implementation for a custom type.
The base implementation for winrt::event_token is straight forward:
cpp:
winrt::event_token MyType::PropertyChanged(winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return propertyChanged_.add(handler);
}
void MyType::PropertyChanged(winrt::event_token const& token)
{
propertyChanged_.remove(token);
}
h:
winrt::event_token PropertyChanged(PropertyChangedEventHandler const& value);
void PropertyChanged(winrt::event_token const& token);
winrt::event<PropertyChangedEventHandler> propertyChanged_;
where MyType is a vanilla runtimeclass
idl:
namespace Test {
[bindable][default_interface]
runtimeclass MyType : Microsoft.UI.Xaml.DependencyObject, Microsoft.UI.Xaml.Data.INotifyPropertyChanged
h:
namespace winrt::Test::implementation {
struct MyType : MyTypeT<MyType>
What i naively tried is to add a
int32_t unregisterPropertyChanged(winrt::event_token token);
to the header, typedef a revoker type there
using PropertyChanged_revoker = winrt::event_revoker<MyType>;
and implement the adder like this:
MyType::PropertyChanged_revoker MyType::PropertyChanged(auto_revoke_t, winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return PropertyChanged_revoker(get_weak(), &MyType::unregisterPropertyChanged, propertyChanged_.add(handler));
}
but it's not that easy and msvc complains about use_make_function_to_create_this_object where the instantiation causing this is here.
I couldn't find any examples and google or msdn weren't really helpful.
Since i'm not crossing abi boundaries i might be able to roll my own implementation which works around this but that feels wrong. Is there a canonical and no that involved way to do this? How to use winrt::event_revoker?
My goal is to put the revoker instances in a std::vector.
EDIT (the hacky workaround):
roll my own implementation which works around this worked; i copied the winrt event_revoker template and changed its revoke method from
void revoke() noexcept
{
if (I object = std::exchange(m_object, {}).get())
{
((*reinterpret_cast<impl::abi_t<I>**>(&object))->*(m_method))(m_token);
}
}
to
void revoke() noexcept
{
if (m_object.get() && m_object.get().get())
{
auto p = m_object.get().get();
m_object = {};
(p->*(m_method))(m_token);
}
}
but it feels wrong.