Windows Runtime dependency properties that depend on each other

Viewed 50

I got a Windows Runtime component authored in C++/CX that contains four dependency properties. Three of those properties set the color channels red, green and blue in the underlying renderer. The C++/C code for one such property looks as follows:

uint8_t DemoControl::Red::get()
{
  return static_cast<uint8_t>(GetValue(RedProperty));
}

void DemoControl::Red::set(uint8_t r)
{
  SetValue(RedProperty, r);
}

DependencyProperty^ DemoControl::_redProperty =
  DependencyProperty::Register("Red",
                               uint_t::typeid,
                               DemoControl::typeid,
                               ref new PropertyMetadata(127, ref new PropertyChangedCallback(&DemoControl::OnRedChanged)));

void DemoControl::OnRedChanged(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
{
  DemoControl^ DemoControl = static_cast<DemoControl^>(d);
  DemoControl->renderer->SetRed(static_cast<uint8_t>(e->NewValue));
}

The fourth property returns the entire color, i.e. it is a combination of the values of the three other properties.

The question is, how would I update that color property if either the red, green or blue property changes without triggering the code attached to the color property via data binding?

A similar question has been asked here but for WPF. The answer suggests to use value coercion but this seems to be a feature unavailable to Windows Runtime components. The PropertyMetadata object used when registering the dependency property does not support CoerceValueCallback from what I can see.

1 Answers

I'm not a C++ expert, but at least for your scenario, I think I can help.

You can register the same callback for multiple Dependency Properties. So in your specific case, you could just have a single OnColorComponentChanged callback:

void DemoControl::OnColorComponentChanged(DependencyObject^ d, DependencyPropertyChangedEventArgs^ e)
{
  DemoControl^ DemoControl = static_cast<DemoControl^>(d);

  if (e->Property == DemoControl::RedProperty) // Hand Wave Syntax Here
  {
    DemoControl->renderer->SetRed(static_cast<uint8_t>(e->NewValue));
  }
  else if (e->Property == DemoControl::GreenProperty)
  {
    DemoControl->renderer->SetGreen(static_cast<uint8_t>(e->NewValue));  
  }
  else if (e->Property == DemoControl::BlueProperty)
  {
    DemoControl->renderer->SetBlue(static_cast<uint8_t>(e->NewValue));  
  }

  // Hand Wave Here
  DemoControl->Color = MakeColor(DemoControl->Red, DemoControl->Green, DemoControl->Blue);
}
Related