dath
dath

Reputation: 915

WPF element height binding lost after animation

In my example app, I have a inner grid's height binded to the main grid's height. When I maximise and minimise the window, their heights are the same. after I execute an animation that changes the inner grid's height from 100 to binding the main grid's height again, the binding is lost. This is evident because when I maximise the window, the inner grids height remains the same while the main grid's height changes to fit the fill height of the window

Why is this and how can I fix it so the inner grid retains the main grid's height after I've set it back to that after an animation.

Example app:

<Window.Resources>
    <Storyboard x:Key="ShrinkSlider" x:Name="ShrinkSlider"
                Completed="ShrinkSlider_Completed">
        <DoubleAnimation
            Storyboard.TargetProperty="Height"
            Storyboard.TargetName="gridSlider"
            DecelerationRatio="0.9"
            From="100"
            To="{Binding ActualHeight, ElementName=gridMain}"
            Duration="00:00:00.5" />
    </Storyboard>

    <Storyboard x:Key="ExpandSlider" x:Name="ExpandSlider"
                Completed="ExpandSlider_Completed">
        <DoubleAnimation
            Storyboard.TargetProperty="Height"
            Storyboard.TargetName="gridSlider"
            DecelerationRatio="0.9"
            From="{Binding ActualHeight, ElementName=gridMain}"
            To="100"
            Duration="00:00:00.5" />
    </Storyboard>
</Window.Resources>

<Window.Triggers>
    <EventTrigger RoutedEvent="ButtonBase.Click"
                  SourceName="btnShrink">
        <BeginStoryboard x:Name="bsbShrinkSlider"
                         Storyboard="{StaticResource ShrinkSlider}" />
    </EventTrigger>

    <EventTrigger RoutedEvent="ButtonBase.Click"
                  SourceName="btnExpand">
        <BeginStoryboard x:Name="bsbExpandSlider"
                         Storyboard="{StaticResource ExpandSlider}" />
    </EventTrigger>
</Window.Triggers>

<Grid x:Name="gridMain">
    <Grid x:Name="gridSlider"
          Background="#1f1f1f"
          VerticalAlignment="Top"
          Height="{Binding ActualHeight, ElementName=gridMain}">
    </Grid>

    <StackPanel VerticalAlignment="Bottom">
        <Button Content="Shrink"
                x:Name="btnShrink"
            Height="20"
                Click="BtnShrink_Click" />
        <Button Content="Expand"
                x:Name="btnExpand"
            Height="20"
                Click="BtnExpand_Click" />
    </StackPanel>
</Grid>

Upvotes: 1

Views: 191

Answers (1)

dath
dath

Reputation: 915

Okay so I figured it out. I needed to set Storyboard FillBehaviour = "Stop"

Then I needed to recreate the binding on the Storyboard Completed event:

        Binding binding = new Binding();
        binding.Source = gridMain;
        binding.Path = new PropertyPath(Grid.ActualHeightProperty);
        gridSlider.SetBinding(Grid.HeightProperty, binding);

Here is the full code amended:

xaml:

<Window.Resources>
    <Storyboard x:Key="ShrinkSlider" x:Name="ShrinkSlider"
                Completed="ShrinkSlider_Completed"
                FillBehavior="Stop">
        <DoubleAnimation
            Storyboard.TargetProperty="Height"
            Storyboard.TargetName="gridSlider"
            DecelerationRatio="0.9"
            From="{Binding ActualHeight, ElementName=gridMain}"
            To="100"
            Duration="00:00:00.5" />
    </Storyboard>

    <Storyboard x:Key="ExpandSlider" x:Name="ExpandSlider"
                Completed="ExpandSlider_Completed"
                FillBehavior="Stop">
        <DoubleAnimation
            Storyboard.TargetProperty="Height"
            Storyboard.TargetName="gridSlider"
            DecelerationRatio="0.9"
            From="100"
            To="{Binding ActualHeight, ElementName=gridMain}"
            Duration="00:00:00.5" />
    </Storyboard>
</Window.Resources>

<Window.Triggers>
    <EventTrigger RoutedEvent="ButtonBase.Click"
                  SourceName="btnShrink">
        <BeginStoryboard x:Name="bsbShrinkSlider"
                         Storyboard="{StaticResource ShrinkSlider}" />
    </EventTrigger>

    <EventTrigger RoutedEvent="ButtonBase.Click"
                  SourceName="btnExpand">
        <BeginStoryboard x:Name="bsbExpandSlider"
                         Storyboard="{StaticResource ExpandSlider}" />
    </EventTrigger>
</Window.Triggers>

<Grid x:Name="gridMain">
    <Grid x:Name="gridSlider"
          Background="#1f1f1f"
          VerticalAlignment="Top"
          Height="{Binding ActualHeight, ElementName=gridMain}">
    </Grid>

    <StackPanel VerticalAlignment="Bottom">
        <Button Content="Shrink"
                x:Name="btnShrink"
            Height="20" />
        <Button Content="Expand"
                x:Name="btnExpand"
            Height="20" />
    </StackPanel>
</Grid>

cs:

private void ShrinkSlider_Completed(object sender, EventArgs e)
    {
        gridSlider.Height = 100;
    }

    private void ExpandSlider_Completed(object sender, EventArgs e)
    {
        Binding binding = new Binding();
        binding.Source = gridMain;
        binding.Path = new PropertyPath(Grid.ActualHeightProperty);
        gridSlider.SetBinding(Grid.HeightProperty, binding);
    }

Upvotes: 1

Related Questions