Вы можете использовать ListBox
для достижения желаемого.
В Silverlight 4 существует новая группа состояний LayoutStates , доступная в стиле ListBoxItem
.
Имеет три визуальных состояния: AfterLoaded
, BeforeUnloaded
и BeforeLoaded
.
Как следует из имен, состояние BeforeLoaded возникает непосредственно перед тем, как ListBoxItem добавляется в ListBox, а состояние AfterLoaded происходит после добавления ListBoxItem.Перед тем как выгрузить произойдет прямо перед удалением ListBoxItem.
В вашем случае вам нужно анимировать постепенное исчезновение (Opacity
и TranslateY
) в состоянии BeforeLoaded
при попытке добавить новую строку текста и анимировать затухание в состоянии BeforeUnloaded
при попытке удалить верхнюю строку.Ниже приведен лишь один простой пример.
<Style x:Key="AnimatedListBoxItemStyle" TargetType="ListBoxItem">
...
<VisualStateGroup x:Name="LayoutStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.4" To="BeforeUnloaded">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="-37" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="1" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition GeneratedDuration="0:0:1" />
</VisualStateGroup.Transitions>
<VisualState x:Name="BeforeUnloaded" />
<VisualState x:Name="BeforeLoaded">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="37" />
<EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="AfterLoaded" />
</VisualStateGroup>
Поскольку после удаления первой строки остальные ListBoxItems
сразу же подпрыгнут, чтобы заполнить пустое пространство.Чтобы сделать этот переход плавным, вы можете перезаписать ListBox
ItemsPanel
обычным StackPanel
и прикрепить к нему FluidMoveBehavior .Помните, чтобы установить AppliesTo
на Children
.Это означает, что анимация произойдет с детьми ListBox
, которые являются ListBoxItems
.
<ItemsPanelTemplate x:Key="ItemsPanelTemplate">
<StackPanel>
<i:Interaction.Behaviors>
<ei:FluidMoveBehavior AppliesTo="Children"/>
</i:Interaction.Behaviors>
</StackPanel>
</ItemsPanelTemplate>
Надеюсь, это поможет.:)
ОБНОВЛЕНИЕ
Вы используете OpacityMask
для создания замирания.
<ScrollViewer Padding="0" HorizontalAlignment="Center" Width="180" Height="300" VerticalAlignment="Center" VerticalScrollBarVisibility="Disabled" BorderThickness="0">
<ScrollViewer.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="Transparent" Offset="0" />
<GradientStop Color="Black" Offset="0.1" />
</LinearGradientBrush>
</ScrollViewer.OpacityMask>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="First Line" FontSize="14.667"/>
<TextBlock Text="Second Line" Grid.Row="1" FontSize="14.667"/>
</Grid>
</ScrollViewer>