У меня есть ListView, который должен отображать довольно большое количество элементов, состоящих из «Name», «Thumbnail» и «AnimationPosition». Фоновая задача в типе каждого элемента отвечает за переключение эскизов, чтобы оживить их.ListView элементов из ObservableCollection, которые должны быть подготовлены к реализации
Теперь само собой разумеется, что это довольно тяжелая операция и должна ограничиваться как можно меньшим количеством элементов, например. для видимых/реализующих элементов виртуализированного ListView. Теперь я уже установил DataContext моего ListView в экземпляр 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?
Update: Вопрос виртуализация не работает должным образом было связано с WrapPanel и когда я переключился на VirtualizingStackPanel он начал работать правильно. К сожалению, это не совсем то же самое, что WrapPanel, и так как .NET framework не предлагает VirtualizingWrapPanel, я решил использовать его с here. Это не идеально, но это делает работу.
Call StartAnimation из GetHashCode. Что касается Stop, я не знаю. – Paparazzi
Спасибо @Blam, он решает половину проблемы. Давайте посмотрим, сможет ли кто-нибудь еще найти решение, которое идет полным ходом. –