Search code examples
winrt-xamluwp-xamlc++-cx

How to register a DependencyProperty that shall work with a value type


In a C++/CX class I want to create a DependencyProperty that gets or sets a normal C++ float value type but I just cannot figure out how I need to specify the type that is expected by the DependencyProperty::Register.

Let me make an example. If I were to use a property that works with a reference type I'd put the following into the header file of my C++/CX class:

public:

  static property Windows::UI::Xaml::DependencyProperty^ BackgroundColorProperty
  {
    Windows::UI::Xaml::DependencyProperty^ get();
  };

  property Windows::UI::Xaml::Media::Brush^ BackgroundColor
  {
    Windows::UI::Xaml::Media::Brush^ get();
    void set(Windows::UI::Xaml::Media::Brush^ value);
  };

private:

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

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

The implementation would look like this:

DependencyProperty^ MyCustomClass::BackgroundColorProperty::get()
{
  return _backgroundColorProperty;
}

Windows::UI::Xaml::Media::Brush^ MyCustomClass::BackgroundColor::get()
{
  return static_cast<Windows::UI::Xaml::Media::Brush^>(GetValue(BackgroundColorProperty));
}

void MyCustomClass::BackgroundColor::set(Windows::UI::Xaml::Media::Brush^ value)
{
  SetValue(BackgroundColorProperty, value);
}

DependencyProperty^ MyCustomClass::_backgroundColorProperty =
  DependencyProperty::Register("BackgroundColor",
                               Brush::typeid,
                               MyCustomClass::typeid,
                               ref new PropertyMetadata(ref new SolidColorBrush(Windows::UI::ColorHelper::FromArgb(255, 255, 255, 255)), ref new PropertyChangedCallback(&MyCustomClass::OnBackgroundColorChanged)));

void MyCustomClass::OnBackgroundColorChanged(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
{
  MyCustomClass^ myClass = static_cast<MyCustomClass^>(d);
  // Do whatever needs to be done
}

This all works. Visual Studio's XAML Designer recognizes that property and everything works as expected.

But lets say I want a property that uses a float instead of the Brush. How would I need to specify the necessary type in the DependencyProperty::Register method? I mean the second argument in the code below.

DependencyProperty^ MyCustomClass::_backgroundColorProperty =
  DependencyProperty::Register("BackgroundColor",
                               /* How do I specify the type of the float here?*/,
                               MyCustomClass::typeid,
                               ref new PropertyMetadata(1.0f, ref new PropertyChangedCallback(&MyCustomClass::OnBackgroundColorChanged)));

I have tried the following which didn't work:

ref new TypeKind(TypeKind::Primitive, float32)
typeof(float32)
typeof(float)
typeid(float)
ref new Windows::UI::Xaml::Interop::TypeKind(TypeKind::Primitive, float)
ref new Windows::UI::Xaml::Interop::TypeKind(TypeKind::Primitive, typeid(float))

Solution

  • You can directly use float::typeid to register float type.

    DependencyProperty^ MyCustomClass::_backgroundColorProperty =
    DependencyProperty::Register("BackgroundColor",
        float::typeid,
        MyCustomClass::typeid,
        ref new PropertyMetadata(1.0f, ref new PropertyChangedCallback(&MyCustomClass::OnBackgroundColorChanged)));
    

    In addition, from this document, it mentions:

    If you want a DP with a floating-point type, then make it double (Double in MIDL 3.0). Declaring and implementing a DP of type float (Single in MIDL), and then setting a value for that DP in XAML markup, results in the error Failed to create a 'Windows.Foundation.Single' from the text ''.

    So I suggest you to use double dependency property instead of float.