Listening to a dependency property changes in Universal Windows App in C++

If you want to be notified when some dependency property of a control changes, for example, UIElement::Visibility, you can do the following trick. First declare you own dependency property of the same type in some class:

public ref class MyListener
{
public:

    static property Windows::UI::Xaml::DependencyProperty ^ BoundVisibilityProperty
    {
        Windows::UI::Xaml::DependencyProperty ^ get() { return boundVisibilityProperty; }
    }

    property Windows::UI::Xaml::Visibility BoundVisibility
    {
        Windows::UI::Xaml::Visibility get() { return safe_cast<Windows::UI::Xaml::Visibility>(GetValue(boundVisibilityProperty)); }
        void set(Windows::UI::Xaml::Visibility value) { SetValue(boundVisibilityProperty, value); }
    }

    static Windows::UI::Xaml::DependencyProperty ^ boundVisibilityProperty;

    static void OnBoundVisibilityChanged(DependencyObject^ d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);
};

than add the property change callback:

Windows::UI::Xaml::DependencyProperty^ MyListener::boundVisibilityProperty = Windows::UI::Xaml::DependencyProperty::Register("BoundVisibility",
    Windows::UI::Xaml::Visibility::typeid, MyListener::typeid,
    ref new Windows::UI::Xaml::PropertyMetadata(Windows::UI::Xaml::Visibility::Collapsed, ref new Windows::UI::Xaml::PropertyChangedCallback(&MyListener::OnBoundVisibilityChanged)));

void MyListener::OnBoundVisibilityChanged(DependencyObject^ d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e)
{
    Windows::UI::Xaml::Visibility new_val = safe_cast<Windows::UI::Xaml::Visibility>(e->NewValue);

    if (new_val == Windows::UI::Xaml::Visibility::Collapsed)
    {
        MyListener ^ page = safe_cast<MyListener ^>(d);

        //do something if the control is hidden
    }
}

now the only thing that you need is to bind your property to the control’s Visibility with the following code:

Windows::UI::Xaml::Data::Binding ^ binding = ref new Windows::UI::Xaml::Data::Binding();

binding->Source = control;
binding->Path = ref new Windows::UI::Xaml::PropertyPath("Visibility");
binding->Mode = Windows::UI::Xaml::Data::BindingMode::OneWay;

Windows::UI::Xaml::Data::BindingOperations::SetBinding(this, CurrentDialogVisibilityProperty, binding);

in C# it looks a bit easier, because in C# you do not need to use long namespaces like Windows::UI::Xaml all the time, but if we add using namespace directive in C++:

using namespace Windows::UI::Xaml;

C++ will not understand the difference between this->Visibility and Windows::UI::Xaml::Visibility.

Leave a Reply

Your email address will not be published. Required fields are marked *