Page 1 of 1

Custom behavior with a group of setters to apply based on a feature flag

Posted: 27 Feb 2024, 18:34
by bridgetfoote
Hi!
I am trying to see if it is possible to create a custom behavior that has a property indicating a feature flag name and a property that is a BaseSetterCollection to apply if the feature flag is enabled. I have overriden OnAttached and check for the state of the feature flag in that function and then if the feature flag is enabled I call the following function:
void ApplySetters(Noesis::BaseSetterCollection* setters)
{
    for (int i = 0; i < setters->Count(); i++)
    {
        Noesis::BaseSetter* setter = setters->Get(i);
        if (setter)
        {
            ApplySetter(setter);
        }
    }
}
I'm just not sure of how to write/if it's possible to write ApplySetter so that we apply the setter property to the associated element.

Re: Custom behavior with a group of setters to apply based on a feature flag

Posted: 29 Feb 2024, 12:03
by sfernandez
Hi,

You should get the value from the getter and apply it to the associated object:
void ApplySetter(BaseSetter* setter)
{
  DependencyObject* dob = GetAssociatedObject();
  if (dob == nullptr) return;
  
  Setter* setter_ = (Setter*)setter;
  const DependencyProperty* dp= setter_->GetProperty();
  BaseComponent* value = setter_->GetValue();
  Expression* expression = DynamicCast<Expression*>(value);
  if (expression != nullptr)
  {
    dob->SetExpression(dp, expression->Reapply(dob, dp));
  }
  else
  {
    dob->SetValueObject(dp, value);
  }
}
Haven't tried the code, but it is mostly what we do internally to apply setter values.
Please let me know if you find any trouble with it.

Re: Custom behavior with a group of setters to apply based on a feature flag

Posted: 29 Feb 2024, 14:33
by bridgetfoote
Thanks for this! I'm also having trouble passing the BaseSetterCollection as a dependency property to the behavior through the xaml. I have the property declared in the header of the behavior like this
static inline const Noesis::DependencyProperty* s_settersProperty;
and then in my cpp file I have this
NS_IMPLEMENT_REFLECTION(ExperimentationBehavior, "ExperimentationBehavior")
{
    NsMeta<Noesis::ContentPropertyMetaData>("Setters");

    Noesis::UIElementData* data = NsMeta<Noesis::UIElementData>(Noesis::TypeOf<SelfClass>());

    data->RegisterProperty<Noesis::String>(s_featureProperty, "Feature", Noesis::PropertyMetadata::Create(Noesis::String{}));
    data->RegisterProperty<Noesis::Ptr<Noesis::BaseSetterCollection>>(s_settersProperty, "Setters", Noesis::PropertyMetadata::Create(Noesis::Ptr<Noesis::BaseSetterCollection>()));
}
and then in the xaml I'm defining the setter collection in the resource dictionary like this
<BaseSetterCollection x:Name="TestSetters">
    <Setter Property="Visibility" Value="Collapsed"/>
</BaseSetterCollection>
and then using it in the behavior like this
<b:Interaction.Behaviors>
    <ExperimentationBehavior Feature="featureFlagName" Setters="{StaticResource TestSetters}" />
</b:Interaction.Behaviors>
but the setters property is null with the message <parent failed to evaluate: parent is NULL>

Re: Custom behavior with a group of setters to apply based on a feature flag

Posted: 29 Feb 2024, 20:04
by bridgetfoote
Actually nevermind the above, I got it to work by instead declaring the setters property in the xaml in this way
<ExperimentationBehavior Feature="featureFlagName">
	<ExperimentationBehavior.Setters>
		<Setter Property="Visibility" Value="Collapsed"/>
		<Setter Property="TextAlignment" Value="Right"/>
	</ExperimentationBehavior.Setters>
</ExperimentationBehavior>
And the group of setters are getting into the behavior with the correct number of setters - however their properties (mProperty) is null. Any guess as to why that would be happening?

Re: Custom behavior with a group of setters to apply based on a feature flag

Posted: 29 Feb 2024, 21:01
by bridgetfoote
Actually, nevermind the above again :) I got it to work but only when the "TargetName" property is also set in the Setter. Any reason why it would only work this way?

Re: Custom behavior with a group of setters to apply based on a feature flag

Posted: 04 Mar 2024, 10:52
by sfernandez
The Setter.Property uses a converter to find the dependency property from the name. In case the Setter is used inside a Style or a Template, if you don't specify a TargetName, it can use the TargetType to resolve the type to search for the property. As you're not inside a Style or Template you need to fully qualify the property name with the type (something like "UIElement.Visibility"), or specify a TargetName.

Could you try that?