Arkadiy_Kolomiets
Topic Author
Posts: 9
Joined: 16 Jun 2024, 07:45

Sending dependency property via xaml to converter

13 Nov 2024, 08:53

In my view i have several dependency properties and depends on their values, i want to update another value by using converter

Here the properties declaration:
        const Noesis::DependencyProperty *SlideButtonUserControlView::ProgressValueProperty;
        const Noesis::DependencyProperty *SlideButtonUserControlView::MaxProgressValueProperty;
        const Noesis::DependencyProperty *SlideButtonUserControlView::MinProgressValueProperty;
Their registration
            auto onProgressValueChanged = [](DependencyObject* d, const Noesis::DependencyPropertyChangedEventArgs& e) {
                const auto control = Noesis::DynamicCast<SlideButtonUserControlView *>(d);
                const auto new_value = *static_cast<const int *>(e.newValue);

                if (new_value == control->getMaxProgressValue()) {
                    control->SetState(eSlideButtonState::E_COMPLETED);
                }
            };

            data->RegisterProperty<int>(ProgressValueProperty, "ProgressValue", Noesis::PropertyMetadata::Create(int(0),
                                         Noesis::PropertyChangedCallback(onProgressValueChanged)));
            data->RegisterProperty<int>(MinProgressValueProperty, "MinProgressValue", Noesis::PropertyMetadata::Create(int(0)));
            data->RegisterProperty<int>(MaxProgressValueProperty, "MaxProgressValue", Noesis::PropertyMetadata::Create(int(100)));
Their usage in the xaml in the converter
<local:cSlideButtonProgressConverter x:Key="SlideButtonProgressConverter"/>

          <DoubleAnimationUsingKeyFrames Storyboard.TargetName="InProgressLeftColorStop"
                                         Storyboard.TargetProperty="Offset">
            <DiscreteDoubleKeyFrame KeyTime="0">
              <DiscreteDoubleKeyFrame.Value>
                <MultiBinding Converter="{StaticResource SlideButtonProgressConverter}" ConverterParameter="LeftColorStop">
                  <Binding ElementName="SlideButtonControl" Path="ProgressValue" />
                  <Binding ElementName="SlideButtonControl" Path="MinProgressValue" />
                  <Binding ElementName="SlideButtonControl" Path="MaxProgressValue" />
                </MultiBinding>
              </DiscreteDoubleKeyFrame.Value>
            </DiscreteDoubleKeyFrame>
          </DoubleAnimationUsingKeyFrames>
Here the converter that receives the dependency properties
        bool cSlideButtonProgressConverter::TryConvert(Noesis::ArrayRef<Noesis::BaseComponent *> values, const Noesis::Type *targetType,
                        Noesis::BaseComponent *param, Noesis::Ptr<Noesis::BaseComponent> &result)  {
            NS_UNUSED(targetType);

            if (values.Size() == 3 && param != nullptr) {
                const auto progress_value = Noesis::Boxing::Unbox<int>(values[0]);
                const auto min_value = Noesis::Boxing::Unbox<int>(values[1]);
                const auto max_value = Noesis::Boxing::Unbox<int>(values[2]);
                Noesis::String conv_param = Noesis::Boxing::Unbox<Noesis::String>(param);

                float scale = (progress_value - min_value) / (max_value - min_value);

                if (conv_param == "LeftColorStop") {
                    scale += default_left_shift;
                } else if (conv_param != "RightColorStop") {
                    result = Noesis::Boxing::Box(0.0f); // Default case
                    return true;
                }

                result = Noesis::Boxing::Box(scale);

                return true;
            }

            return false;
        }
After changing the progress value in the converter I get a garbage value of min and max If I don't change the default min and max value from the outside, how can I solve this problem?
 
User avatar
sfernandez
Site Admin
Posts: 3183
Joined: 22 Dec 2011, 19:20

Re: Sending dependency property via xaml to converter

14 Nov 2024, 12:17

Hi, in a MultiValueConverter the values array can contain the unset value (DependencyProperty::GetUnsetValue()) while not all the bindings are solved.
You can check for that in your converter to use a default value until everything gets resolved:
const auto progress_value = Noesis::Boxing::CanUnbox<int>(values[0]) ? Noesis::Boxing::Unbox<int>(values[0]) : 0;
const auto min_value = Noesis::Boxing::CanUnbox<int>(values[1]) ? Noesis::Boxing::Unbox<int>(values[1]) : 0;
const auto max_value = Noesis::Boxing::CanUnbox<int>(values[2]) ? Noesis::Boxing::Unbox<int>(values[2]) : 100;
Could you try that?
 
Arkadiy_Kolomiets
Topic Author
Posts: 9
Joined: 16 Jun 2024, 07:45

Re: Sending dependency property via xaml to converter

01 Dec 2024, 11:31

I am very grateful for the answer and this solution, but this is a tricky solution that does not solve the real problem. It only provides a placeholder that proves that infrastructure doesn't work properly. When I use converters with properties from the View Model, I don't meet the problem with unresolved symbols
 
User avatar
sfernandez
Site Admin
Posts: 3183
Joined: 22 Dec 2011, 19:20

Re: Sending dependency property via xaml to converter

03 Dec 2024, 10:58

If you can't use fallback values, then just return false in the converter while all the bindings get solved:
bool cSlideButtonProgressConverter::TryConvert(Noesis::ArrayRef<Noesis::BaseComponent *> values, const Noesis::Type *targetType,
  Noesis::BaseComponent *param, Noesis::Ptr<Noesis::BaseComponent> &result)  {
  if (values.Size() == 3 && param != nullptr &&
    values[0] != DependencyProperty::GetUnsetValue() &&
    values[1] != DependencyProperty::GetUnsetValue() &&
    values[2] != DependencyProperty::GetUnsetValue()) {
      ...
  }
  return false;
}
Is this what you're looking for?

Who is online

Users browsing this forum: Bing [Bot], BrandonReinhart, Google [Bot] and 9 guests