Page 1 of 1

Behaviour<T> + VisualStateManager - Templates not applied

Posted: 23 Feb 2021, 02:36
by steveh
Hi guys, I'm trying to use a custom Behaviour<T> with the VisualStateManager:
/*virtual*/ void CustomButtonBehaviour::OnAttached() /*override*/
{
    Button *pBaseButton = GetAssociatedObject();
    pBaseButton->DependencyPropertyChanged() += MakeDelegate(this, &OnPropertyChanged);
}

void CustomButtonBehaviour::OnPropertyChanged(BaseComponent*, const DependencyPropertyChangedEventArgs &rArgs)
{
    if (rArgs.prop == ContentControl::ContentProperty)
    {
        Button *pButton = GetAssociatedObject();
	if (nullptr != pButton->GetContent())
	{
	    VisualStateManager::GoToState(pButton, NSS(CustomVisualState), false);
	}
    }
}
This fails to run as the template is not yet applied. There is not a nice way from what I can see to hook in to add this behaviour. Normally in Custom Controls I'd derive from OnApplyTemplate virtual and add this behaviour here, is there an alternative for behaviours?

My workaround is to force ApplyTemplate:
void CustomButtonBehaviour::OnPropertyChanged(BaseComponent*, const DependencyPropertyChangedEventArgs &rArgs)
{
    if (rArgs.prop == ContentControl::ContentProperty)
    {
        Button *pButton = GetAssociatedObject();
	if (nullptr != pButton->GetContent())
	{
	    pButton->ApplyTemplate(); // Force apply template so visual child is set
	    VisualStateManager::GoToState(pButton, NSS(CustomVisualState), false);
	}
    }
}
But this doesn't feel clean. Any ideas? Cheers!

-Steven

Re: Behaviour<T> + VisualStateManager - Templates not applied

Posted: 23 Feb 2021, 10:45
by sfernandez
Hi, in situations where you need controls to have their template already applied you can explicitly call ApplyTemplate() as you did, or you can hook to Loaded event, which happens after control has been measured, so its template is ready.

Cheers.

Re: Behaviour<T> + VisualStateManager - Templates not applied

Posted: 23 Feb 2021, 12:01
by steveh
Cheers Sergio!

I tried using the Loaded event but it seemed in my case that this didn't work, I think it was due to the ContentControl initially having a binding for the content set to NULL so the inner ContentTemplate was invalid until we load into our game much later down the line.

As long as manually applying the template is fine then that's fine with me, I just thought I'd check first to see if there was a different solution. Much appreciated!

-Steven

Re: Behaviour<T> + VisualStateManager - Templates not applied

Posted: 23 Feb 2021, 12:09
by sfernandez
Yes, you can simply use ApplyTemplate() in this case. Thanks for the update.