ScrollViewer里面的列表框 - 冻结程序

时间:2017-02-24 22:02:03

标签: c# wpf xaml listbox scrollview

我需要一些建议。我们注意到ScrollViewer中的异常行为。我有一个StackPanel,当StackPanel放在ScrollViewer中时,我更多的项目包括ListBox,当将数据加载到列表框时,程序暂时冻结。当我独自一人时ListBox,但一切正常,没有冻结程序。

这是我的代码:

  <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"));
            });


        }
    }

有谁知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

垂直定向的StackPanel在布局期间为ListBox调用MeasureOverride(Size availableSize)方法时为ListBox提供了无限的可用空间。因此,<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> (默认情况下使用虚拟化)应创建整个项目,这就是您暂时冻结程序的原因。

因此,请改用DockPanel:

LastChildFill

Height默认为true。 ListBox应该是最后一个元素,以填充空格。

作为另一种选择,您可以设置ListBox的{​​{1}}并将DockPanel放在ScrollViewer中,或者您可以考虑使用分割器Grid作为另一种选择。