C# ScrollViewer中的列表框-冻结程序
我需要一些建议。我们注意到ScrollViewer中的异常行为。我有一个StackPanel,当StackPanel放置在ScrollViewer中时,我可以与它共享更多项目,包括ListBox,当将数据加载到ListBox时,一个程序会短暂冻结。当我一个人在列表框中但一切正常时,程序不会冻结 这是我的密码:C# ScrollViewer中的列表框-冻结程序,c#,wpf,xaml,listbox,scrollview,C#,Wpf,Xaml,Listbox,Scrollview,我需要一些建议。我们注意到ScrollViewer中的异常行为。我有一个StackPanel,当StackPanel放置在ScrollViewer中时,我可以与它共享更多项目,包括ListBox,当将数据加载到ListBox时,一个程序会短暂冻结。当我一个人在列表框中但一切正常时,程序不会冻结 这是我的密码: <ScrollViewer VerticalScrollBarVisibility="Auto"> <StackPanel x:Name="tStac
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="tStack" >
<Grid Height="300">
</Grid>
<Grid Height="300">
</Grid>
<ListBox x:Name="ListBox1" ItemsSource="{Binding AlbumsCvs.View, IsAsync=True}"
Style="{StaticResource ListBoxAlbumsTracksStyles}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource AlbumsHeader}" />
</ListBox.GroupStyle>
</ListBox>
</StackPanel>
</ScrollViewer>
<Style x:Key="ListBoxAlbumsTracksStyles" TargetType="{x:Type ListBox}">
<Setter Property="Padding" Value="0,0,0,0" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate >
<DockPanel>
<Border Background="#00000000"
Height="36"
Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}">
<DockPanel>
<TextBlock x:Name="TrackNumber"
DockPanel.Dock="Left" Margin="2,0,5,0"
Text="{Binding TrackNumber}"
VerticalAlignment="Center"
FontSize="13"
MinWidth="17"
Foreground="Black"/>
<DockPanel>
<TextBlock DockPanel.Dock="Left"
Text="{Binding TrackTitle}"
TextAlignment="Left"
FontSize="13"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Margin="0,0,2,0"/>
<TextBlock DockPanel.Dock="Right"
Text="{Binding Duration}"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Margin="0,0,10,0"
FontSize="13" TextAlignment="Right"/>
</DockPanel>
</DockPanel>
</Border>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- GroupItem -->
<Style x:Key="AlbumsHeader" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}" Background="#00000000">
<StackPanel Margin="0,0,0,15">
<StackPanel>
<TextBlock Text="{Binding AlbumName}"
DataContext="{Binding Items}"
Margin="0,5,0,0"
HorizontalAlignment="Stretch"
FontSize="20"
FontWeight="Light"
TextTrimming="CharacterEllipsis"
Foreground="Black"/>
<TextBlock Text="{Binding IdAlbum}"
DataContext="{Binding Items}"
Margin="0,0,0,10"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Foreground="Black"/>
</StackPanel>
<ItemsPresenter HorizontalAlignment="Stretch"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
代码隐藏:
private async Task AlbumsArtistInformation()
{
if (string.IsNullOrEmpty(ArtistName))
return;
ObservableCollection<AlbumsArtistCollections> _albumsArtistCollections =
new ObservableCollection<AlbumsArtistCollections>();
try
{
var search = await spotifyDataService.GetArtists(ArtistName);
if (search == null) throw new ArgumentNullException(nameof(search));
foreach (var _artist in search.Artists.Items.Take(1))
{
this.IdArtist = _artist.Id;
}
var _artistAlbum = await spotifyDataService.GetArtistsAlbumsAsync(this.IdArtist, AlbumType.All);
if (_artistAlbum == null) throw new ArgumentNullException(nameof(_artistAlbum));
_albumsArtistCollections = _artistAlbum;
}
finally
{
// Unbind to improve UI performance
Application.Current.Dispatcher.Invoke(() =>
{
this.Albums = null;
this.AlbumsCvs = null;
});
Application.Current.Dispatcher.Invoke(() =>
{
this.Albums = _albumsArtistCollections;
});
Application.Current.Dispatcher.Invoke(() =>
{
// Populate CollectionViewSource
this.AlbumsCvs = new CollectionViewSource { Source = this.Albums };
//Group by Album if needed
this.AlbumsCvs.GroupDescriptions.Add(new PropertyGroupDescription("IdAlbum"));
});
}
}
private async Task AlbumsArtistInformation()
{
if(string.IsNullOrEmpty(ArtistName))
返回;
可观察到的集合\u albumsArtistCollections=
新的可观察集合();
尝试
{
var search=wait spotifyDataService.GetArtists(ArtistName);
如果(search==null)抛出新的ArgumentNullException(nameof(search));
foreach(搜索中的艺术家变量。艺术家。项目。获取(1))
{
this.IdArtist=\u artist.Id;
}
var_artistAlbum=wait spotifyDataService.GetArtistsAlbumsAsync(this.IdArtist,AlbumType.All);
如果(_artistAlbum==null)抛出新的ArgumentNullException(nameof(_artistAlbum));
_唱片集=_artistAlbum;
}
最后
{
//取消绑定以提高UI性能
Application.Current.Dispatcher.Invoke(()=>
{
这个.Albums=null;
this.AlbumsCvs=null;
});
Application.Current.Dispatcher.Invoke(()=>
{
this.Albums=\u albumsArtistCollections;
});
Application.Current.Dispatcher.Invoke(()=>
{
//填充CollectionViewSource
this.AlbumsCvs=newcollectionviewsource{Source=this.Albums};
//如果需要,按相册分组
这个.AlbumsCvs.groupdescription.Add(新属性groupdescription(“IdAlbum”));
});
}
}
有人知道如何解决这个问题吗。垂直方向的StackPanel在布局期间调用方法时为
列表框提供了无限的可用空间。因此,列表框
(默认情况下使用虚拟化)应该创建整个项目,这就是为什么您的程序会冻结一段时间
因此,请改用DockPanel:
<DockPanel x:Name="tStack" LastChildFill="True" >
<Grid DockPanel.Dock="Top" Height="300">
</Grid>
<Grid DockPanel.Dock="Top" Height="300">
</Grid>
<ListBox DockPanel.Dock="Bottom" x:Name="ListBox1" ItemsSource="{Binding AlbumsCvs.View, IsAsync=True}"
Style="{StaticResource ListBoxAlbumsTracksStyles}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource AlbumsHeader}" />
</ListBox.GroupStyle>
</ListBox>
</DockPanel>
默认情况下,LastChildFill
为true。列表框应该是最后一个元素,以便填充空间
< P>作为另一个选项,您可以设置<代码> ListBox < /C> >代码> DOCKPUT/<代码> < <代码> ScrollViewer <代码>,或者您可以考虑使用“拆分器”作为另一个选项来选择< <代码>网格>代码> 丢弃堆栈面板并使用它所使用的网格。StackPanel不会为滚动和虚拟化等操作调用面板边界。