views:

44

answers:

0

Hi,

I'd like to animate items as they come into and are removed from a listbox. Essentially, I want the newly added item to animate to its position at the top of the list (from some predetermined coordinate), and have the items in the list animate down a "step" to make room.

I started trying to solve this problem by inheriting form listbox and adding an ItemAdded routed event from which I could trigger the animation. I used a Canvas as my ItemsPanelTemplate. The code below throws a "Cannot freeze this Storyboard timeline tree for use across threads." error message, which is extraordinarily baffling to me. Am I going about this all wrong? This seems like something WPF/XAML would be perfect for, but I'm lost.

Below is the XAML and Converter code. The Converter calculates the Canvas.Top position based on the item's index in the list.

                </Canvas>
            </ItemsPanelTemplate>
        </zwk:MyListBox.ItemsPanel>
        <zwk:MyListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Style.Triggers>
                    <EventTrigger RoutedEvent="zwk:MyListBox.ItemAdded">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Canvas.Top" From="0" 
                                                 To="{Binding Path=., Converter={StaticResource myConverter}}" >

                                </DoubleAnimation>

                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Style.Triggers>
                <Setter Property="Canvas.Left" Value="10"/>
            </Style>
        </zwk:MyListBox.ItemContainerStyle>
        <zwk:MyListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Value}"></TextBlock>
            </DataTemplate>
        </zwk:MyListBox.ItemTemplate>
    </zwk:MyListBox>



    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ViewModel.Items.IndexOf((MyListItem)value) * 10;
    }