开发者

How to make a specific GoToStateAction-with-DataTrigger run when element is loaded

开发者 https://www.devze.com 2023-01-10 17:51 出处:网络
I have a DataTemplate. It has two visual states - Expanded, Collapsed. I added 2 GoToStateAction-s. The first one goes to the Expanded state when a data context property becomes True, and the second o

I have a DataTemplate. It has two visual states - Expanded, Collapsed. I added 2 GoToStateAction-s. The first one goes to the Expanded state when a data context property becomes True, and the second one goes to the Collapsed state when that same property becomes False.

A Checkbox is part of the template and bound to that property. So when the Checkbox gets checked/unchecked the necessary transition happens.

But none of the actions are applied on sta开发者_JAVA技巧rtup. The Checkbox is Checked but the Expanded visual state is not applied.

Is it possible using the Visual State Manager to have all items loaded with states applied according to the property values?


It sounds like you need to override OnApplyTemplate and call VisualStateManager.GoToState(). What happened was your control was loaded, data binding occurred, and then the template was applied. Thus the template is in the base state because nothing told it to perform a state transition. You might be able to do it all from XAML by hooking into the loaded event, but you might find it to be flaky.


You just need to add another GoToStateAction that sets the desired states upon the OnLoad event firing.

update

I haven't tested this, but I think you could use a custom TargetedTriggerAction that derives from GoToStateAction:

public class GoToStateIfCheckedAction : GoToStateAction
{
    protected override void Invoke(object parameter)
    {
        var toggleButton = Target as ToggleButton;
        if (toggleButton != null && (!toggleButton.IsChecked.HasValue || !toggleButton.IsChecked.Value))
        {
            // if the Target is a ToggleButton, and it is in an indeterminate or unchecked state, don't invoke
            return;
        }

        // if the Target is not a ToggleButton, or if the ToggleButton is checked, go ahead and invoke the action
        base.Invoke(parameter);
    }
}

When attached to a ToggleButton, such as CheckBox, this action will only be executed when IsChecked == true.

You could trigger this from the OnLoad event and it will go to the state if the box is checked, or do nothing if unchecked.


I have a similar problem that a binded visual state is not applied on view load:

<core:PropertyChangedTrigger Binding="{Binding State}">
    <core:GoToStateAction StateName="{Binding State}" />
</core:PropertyChangedTrigger>

As I am using MVVM architecture I cannot override the view's OnApplyTemplate as the view cannot 'see' the ViewModel.

Finally, I found that EventTrigger helps and I want to share it with you:

<interactivity:Interaction.Triggers>
    <interactivity:EventTrigger>
        <core:GoToStateAction StateName="{Binding State}" />
    </interactivity:EventTrigger>
    <core:PropertyChangedTrigger Binding="{Binding State}">
        <core:GoToStateAction StateName="{Binding State}" />
    </core:PropertyChangedTrigger>
</interactivity:Interaction.Triggers>

where xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"

0

精彩评论

暂无评论...
验证码 换一张
取 消