1

I have a observable collection of 10 objects binded in a itemscontrol canvas . Each object has a different canvas.right canvas.top value. The ideea was to click on the object to edit it , the object should move to a certain position , edit it and when its done click on it to go back to its original position. So i used a checkbox to have a datatriger for the animation , i have two animations one for edit the other for going back. Problem is that only the first animation fires the second never so the control never moves back to its position.

enter image description here

Here is the code:

<ItemsControl ItemsSource="{Binding SelectedButtonForEdit.Layers}">
                    <ItemsControl.Template>
                        <ControlTemplate TargetType="ItemsControl">
                            <Canvas IsItemsHost="True"/>
                        </ControlTemplate>
                    </ItemsControl.Template>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="ContentPresenter">
                            <Setter Property="Canvas.Right" x:Name="right" Value="{Binding CanvasRight}"/>
                            <Setter Property="Canvas.Top" x:Name="top" Value="{Binding CanvasTop}"/>
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <CheckBox Width="342" Height="156" IsChecked="{Binding IsEditing}" BorderBrush="Black" BorderThickness="1" Style="{StaticResource MaterialDesignRaisedAccentButton}" Background="{Binding Name,Converter={StaticResource LayerNameToColor}}" >
                                            <Grid VerticalAlignment="Stretch">
                                                <Grid.RowDefinitions>
                                                    <RowDefinition />
                                                    <RowDefinition Height="3*"/>
                                                    <RowDefinition Height="*"/>
                                            </Grid>
                                        </CheckBox>
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <DataTrigger  Binding="{Binding IsEditing}" Value="False">
                                    <DataTrigger.EnterActions>
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)" Duration="0:0:0:0.1" ></DoubleAnimation>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   Duration="0:0:0:0.1" ></DoubleAnimation>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </DataTrigger.EnterActions>
                                </DataTrigger>

                            <DataTrigger  Binding="{Binding IsEditing}" Value="True">
                                    <DataTrigger.ExitActions>
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)"  To="200" Duration="0:0:0:0.1" ></DoubleAnimation>
                                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   To="150" Duration="0:0:0:0.1" ></DoubleAnimation>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </DataTrigger.ExitActions>
                                </DataTrigger>
                            </Style.Triggers>

                        </Style>
                    </ItemsControl.ItemContainerStyle>
                </ItemsControl>
adi sba
  • 621
  • 1
  • 12
  • 32

1 Answers1

2

On your first trigger, you have a EnterActions, and on the second you have ExitActions. But in your case, you only need 1 trigger, with both EnterActions and ExitActions, like so :

<DataTrigger  Binding="{Binding IsEditing}" Value="True">
    <DataTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)"  To="200" Duration="0:0:0:0.1" ></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   To="150" Duration="0:0:0:0.1" ></DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </DataTrigger.EnterActions>
    <DataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Right)" Duration="0:0:0:0.1"></DoubleAnimation>
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)"   Duration="0:0:0:0.1"></DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </DataTrigger.ExitActions>
</DataTrigger>

In the code I provided, when IsEditing will turn to True, the animation will move the object to 200,150, and when IsEditing will turn to false, will go back to the original values.

mgarant
  • 565
  • 5
  • 18
  • Thanks but Binding the "To" prop leads to System.InvalidOperationException: 'Cannot freeze this Storyboard timeline tree for use across threads.' – adi sba Mar 20 '20 at 14:39
  • You can find a solution for the binding problem here : https://stackoverflow.com/questions/1669750/wpf-animation-cannot-freeze-this-storyboard-timeline-tree-for-use-across-thread/1669802 – mgarant Mar 21 '20 at 15:11
  • Actually i think it works fine without add To="{Binding CanvasRight}" to the exit action... because it goes to the oringinal point if you adjust your answer il mark it as corect – adi sba Mar 22 '20 at 09:24