在 WPF 中滚动时的动画列表框项目
Animated ListBox Item when scrolling in WPF
我需要建议。如何通过滚动创建列表框中项目的动画,请参见图片。我需要在使用 WrapPanel 时实现相同的动画效果。我很乐意提供任何建议。
滚动时动画淡入淡出
这是代码
<!--VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.CacheLengthUnit="Pixel"
VirtualizingStackPanel.CacheLength="100,100"
VirtualizingStackPanel.ScrollUnit="Pixel"
VirtualizingStackPanel.VirtualizationMode="Recycling"-->
<ListBox x:Name="ListBox1" ItemsSource="{Binding MoviesCvs.View,IsAsync=True}"
Style="{StaticResource CommonListBoxStyle}"
HorizontalContentAlignment="Stretch"
IsSynchronizedWithCurrentItem="False"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<!--<VirtualizingStackPanel IsItemsHost="True"/>-->
<WrapPanel Orientation="Vertical" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0" Background="Transparent" Height="460" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}">
<Grid Background="Transparent" HorizontalAlignment="Left" Width="250" Height="460" Margin="0">
<StackPanel VerticalAlignment="Top">
<cachedImage:Image Stretch="Uniform" ImageUrl="{Binding PosterPath}" >
<cachedImage:Image.Triggers>
<!-- Opacity animation -->
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.8" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</cachedImage:Image.Triggers>
<!-- ********************** -->
</cachedImage:Image>
<TextBlock Margin="5,10,5,0" Text="{Binding MovieTitle}" TextTrimming="CharacterEllipsis" Foreground="Black" TextWrapping="Wrap" MaxHeight="50" FontSize="17"/>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我以某种方式解决了它。我发现了这个:http://munnaondotnet.blogspot.com/2011/09/is-item-is-visible-in-scroll-viewer.html
然后我只是编辑了一点xaml
<ListBox.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer1" ScrollChanged="HandleScrollChanged"
CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<Grid x:Name="GridRoot" Width="250" Height="460" Background="Red" >
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.8" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
和代码隐藏
private void HandleScrollChanged(object sender, ScrollChangedEventArgs e)
{
ShowVisibleItems(sender);
}
private void ShowVisibleItems(object sender)
{
var scrollViewer = (FrameworkElement)sender;
foreach (var item in this.ListBox1.Items)
{
var listBoxItem = (FrameworkElement)this.ListBox1.ItemContainerGenerator.ContainerFromItem(item);
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(listBoxItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
Grid target = (Grid)myDataTemplate.FindName("GridRoot", myContentPresenter);
if (IsFullyOrPartiallyVisible(listBoxItem, scrollViewer))
{
target.Visibility = Visibility.Visible;
}
else
{
target.Visibility = Visibility.Collapsed;
}
}
}
private bool IsFullyOrPartiallyVisible(FrameworkElement element, FrameworkElement container)
{
if (element == null || container == null)
return false;
if (element.Visibility != Visibility.Visible)
return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}
我需要建议。如何通过滚动创建列表框中项目的动画,请参见图片。我需要在使用 WrapPanel 时实现相同的动画效果。我很乐意提供任何建议。
滚动时动画淡入淡出
这是代码
<!--VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.CacheLengthUnit="Pixel"
VirtualizingStackPanel.CacheLength="100,100"
VirtualizingStackPanel.ScrollUnit="Pixel"
VirtualizingStackPanel.VirtualizationMode="Recycling"-->
<ListBox x:Name="ListBox1" ItemsSource="{Binding MoviesCvs.View,IsAsync=True}"
Style="{StaticResource CommonListBoxStyle}"
HorizontalContentAlignment="Stretch"
IsSynchronizedWithCurrentItem="False"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<!--<VirtualizingStackPanel IsItemsHost="True"/>-->
<WrapPanel Orientation="Vertical" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0" Background="Transparent" Height="460" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}">
<Grid Background="Transparent" HorizontalAlignment="Left" Width="250" Height="460" Margin="0">
<StackPanel VerticalAlignment="Top">
<cachedImage:Image Stretch="Uniform" ImageUrl="{Binding PosterPath}" >
<cachedImage:Image.Triggers>
<!-- Opacity animation -->
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.8" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</cachedImage:Image.Triggers>
<!-- ********************** -->
</cachedImage:Image>
<TextBlock Margin="5,10,5,0" Text="{Binding MovieTitle}" TextTrimming="CharacterEllipsis" Foreground="Black" TextWrapping="Wrap" MaxHeight="50" FontSize="17"/>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我以某种方式解决了它。我发现了这个:http://munnaondotnet.blogspot.com/2011/09/is-item-is-visible-in-scroll-viewer.html
然后我只是编辑了一点xaml
<ListBox.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer1" ScrollChanged="HandleScrollChanged"
CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>
<Grid x:Name="GridRoot" Width="250" Height="460" Background="Red" >
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.8" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
和代码隐藏
private void HandleScrollChanged(object sender, ScrollChangedEventArgs e)
{
ShowVisibleItems(sender);
}
private void ShowVisibleItems(object sender)
{
var scrollViewer = (FrameworkElement)sender;
foreach (var item in this.ListBox1.Items)
{
var listBoxItem = (FrameworkElement)this.ListBox1.ItemContainerGenerator.ContainerFromItem(item);
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(listBoxItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
Grid target = (Grid)myDataTemplate.FindName("GridRoot", myContentPresenter);
if (IsFullyOrPartiallyVisible(listBoxItem, scrollViewer))
{
target.Visibility = Visibility.Visible;
}
else
{
target.Visibility = Visibility.Collapsed;
}
}
}
private bool IsFullyOrPartiallyVisible(FrameworkElement element, FrameworkElement container)
{
if (element == null || container == null)
return false;
if (element.Visibility != Visibility.Visible)
return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}