Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fade out removing item from itemscontrol

I have a WPF-View with an ItemsControl that binds an ObservableCollection from the ViewModel. Now i want to fade out slowly items which i remove from the ObservableCollection.

ViewModel:

public class ViewModel
{
    public ObservableCollection<string> Items { get; set; }
}

View:

<Window x:Class="Sandbox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"
    Name="mainWindow">
<Window.Resources>
    <DataTemplate x:Key="mytemplate">
        <DataTemplate.Resources>
            <Storyboard x:Key="OnUnloaded">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="grid">
                    <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="-0"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="grid">
                    <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="-10"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </DataTemplate.Resources>
        <Grid x:Name="grid" RenderTransformOrigin="0.5,0.5">
            <Grid.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform/>
                </TransformGroup>
            </Grid.RenderTransform>
            <TextBox Text="{Binding Mode=OneWay}"/>
        </Grid>
        <DataTemplate.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Unloaded">
                <BeginStoryboard Storyboard="{StaticResource OnUnloaded}"/>
            </EventTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</Window.Resources>
<StackPanel>
    <ItemsControl Grid.Row="1" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource mytemplate}"/>
</StackPanel>

The problem i have is now, that the storyboard begins by removing an item from the collection, but at the same time the itemscontrol remove the item and for this, the animation is not in sight...

any idea how to prevent remove the item before animation terminate?

like image 341
rhe1980 Avatar asked Jan 19 '23 03:01

rhe1980


1 Answers

This is much more difficult than it should be. The problem with a "remove" animation is that once an item is removed from the databound collection, its corresponding visuals are automatically removed from the element tree. This means that there is nothing left to animate out.

To work around it, you need to find a way to queue the animation before you remove the item from the databound collection and once the animation is complete, notify the ViewModel that it is okay to remove the item.

The other solution is to modify the behavior of the ItemsControl to better control the lifetime of the container visuals.

Either way, it is unfortunately not a trivial task to accomplish.

like image 51
sellmeadog Avatar answered Mar 31 '23 12:03

sellmeadog