我有一个ListView,它应该显示由“Name”,“Thumbnail”和“AnimationPosition”属性组成的大量项目。每个项目类型中的后台任务负责切换缩略图,以便为它们制作动画。来自ObservableCollection的ListView项目需要为实现做好准备
现在不言而喻,这是一个相当繁重的操作,应该限制在尽可能少的项目上,例如,以可见/实现虚拟化ListView的项目。现在我已经将ListView的DataContext设置为ObeservableCollection实例,并将其绑定到其类型的属性。以下是我的XAML代码。
<TabControl Grid.Row="0" Grid.Column="2">
<TabControl.Resources>
<Style x:Key="MediaItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Margin" Value="5,5,5,5"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Height="Auto" >
<Border x:Name="border" BorderBrush="{x:Null}" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="2.5"/>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="custom:MediaContainerListView">
<Setter Property="ItemsSource" Value="{Binding}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource MediaItemStyle}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<DockPanel Width="256">
<Image DockPanel.Dock="Top" Height="144" StretchDirection="Both"
Stretch="Fill" Source="{Binding Thumbnail.Source,Mode=OneWay}"/>
<ProgressBar DockPanel.Dock="Top" Height="2"
Minimum="0" Maximum="{Binding Thumbnail.AnimationPosition.Length}"
Value="{Binding Thumbnail.AnimationPosition.Position}"
Visibility="{Binding Thumbnail.AnimationPosition.Visibility}"/>
<TextBlock DockPanel.Dock="Bottom" Height="40"
TextWrapping="Wrap" TextTrimming="CharacterEllipsis"
TextAlignment="Center" Text="{Binding Name}"/>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="">
<custom:MediaContainerListView x:Name="MediaContainerView"></custom:MediaContainerListView>
</TabItem>
</TabControl>
基本上,我有两种方法开始/停止每个单独项目的动画。
public async void StartAnimation()
{
if(Count > 1)
{
Task thumbnailAnimationTask = AnimationTask(AnimationCancellationToken.Token);
await thumbnailAnimationTask;
}
}
public void StopAnimation()
{
AnimationCancellationToken.Cancel();
}
我在这里有两个问题。
- ListView似乎意识到所有的项目,而不仅仅是那些可见或实现范围内的项目。我怀疑我的XAML以某种方式杀死了虚拟化,并尝试了许多没有成功的解决方案。请注意,我需要我的ListView可扩展到MainWindow的尺寸,而不是固定的高度和宽度。
- 我需要在项目即将实现时调用StartAnimation,并在它离开视图时调用StopAnimation。
即使我的ListView控件没有正确的虚拟化,如果我的ObservableCollections工作是如何正确的认识,它只是由虚拟化管理项目的UI表现,而不是项目本身即调用StartAnimation/StopAnimation从项目的构造函数/析构函数中得到的帮助没有多大帮助,因为无论如何它们在创建时都会被调用。
有没有一种简洁的方式来通知每个项目他们即将实现或离开ListView视图?
更新: 虚拟化工作不正常是相关WrapPanel有一次我切换到VirtualizingStackPanel它开始正常工作的问题。不幸的是,它与WrapPanel不完全相同,并且由于.NET框架不提供1 VirtualizingWrapPanel,我选择使用here中的一个。这并不完美,但它完成了这项工作。
从GetHashCode调用StartAnimation。至于停止,我不知道。 – Paparazzi
谢谢@Blam,它解决了一半的问题。让我们看看是否有其他人能够想出一个可以一路走下去的解决方案。 –