RadekVyM / SimpleToolkit

SimpleToolkit is a .NET MAUI library of helpers and simple, fully customizable controls, such as SimpleShell - custom Shell implementation that allows you to create unique navigation experiences.
MIT License
425 stars 41 forks source link

Probably Behaviors not working in Simpleshell #43

Open KannanKrish opened 6 months ago

KannanKrish commented 6 months ago

My xaml markup code is (code have the behavior)

<simpleShell:SimpleShell.Content>
    <Grid RowDefinitions="50, *">
        ...
        <Grid x:Name="MenuContent"
              Grid.Row="0"
              Grid.RowSpan="2"
              IsVisible="False">
            ...
                <Grid.Behaviors>
                    <IsVisibleAnimBehavior x:Name="IsVisibleAnimBehavior" ChangeVisibility="True" />
                    <PositionAnimBehavior AnimationDuration="300" Easing="{x:Static Easing.BounceOut}" StartPositionX="-400" />
                </Grid.Behaviors>

            </Grid>
        </Grid>
    </Grid>
</simpleShell:SimpleShell.Content>

IsVisibleAnimBehavior behavior is responsible for triggering the animation whenever the visibility changes.

When app runs, I got exception like

System.ArgumentException: 'Unable to find IAnimationManager for 'Microsoft.Maui.Controls.Grid'. (Parameter 'animatable')'

The behavior works fine with normal Content Page.

RadekVyM commented 3 months ago

Hi @KannanKrish, apologies for my late response - this library has not been my number one priority recently.

I tried to look at this issue and did some simple tests. I am not 100% certain, but I think that your behaviors are trying to execute the animations too early. I think that following is happening. When the animation is started, the GetAnimationManager() method is called. This method tries to access MauiContext through view's handler which is not created yet.

Could you please try to move the first execution of the animation into a Loaded callback? When the Loaded event is raised, MauiContext is accessible and GetAnimationManager() should not throw an exception.

public class MyBehavior : Behavior<View>
{
    protected override void OnAttachedTo(View bindable)
    {
        bindable.Loaded += static (sender, e) =>
        {
            if (sender is not View loadedBindable)
                return;

            // View is loaded and MauiContext should be accessible. Do the work with loadedBindable...

        };

        // MauiContext is not accessible yet...

        base.OnAttachedTo(bindable);
    }

    // Other code...
}