Фильтр CollectionView замораживает пользовательский интерфейс, когда высота не фиксирована?

#c# #wpf #filter #listbox #collectionview

#c# #wpf #Фильтр #список #collectionview

Вопрос:

У меня есть ListBox, который привязан к данным ObservableCollection и имеет сложный ItemContainerStyle (с изображениями, индикаторами выполнения и текстом)

Когда я пытаюсь применить фильтр к его CollectionView, в коллекции около 200 элементов, пользовательский интерфейс зависает на 2-3 секунды. Это происходит только тогда, когда высота списка не фиксирована (т.Е. Разрешено расти). Это происходит мгновенно, когда высота списка установлена на значение, например 500

 <Style x:Key="CollectionStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Border x:Name="Bd" VerticalAlignment="Center" BorderBrush="Transparent" BorderThickness="1" CornerRadius="3.5" Margin="2" Padding="2">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="50"/>
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Source="{Binding Path=ListIcon}" Width="32" Margin="5,5,0,5" VerticalAlignment="Center" />
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <StackPanel Orientation="Horizontal" Margin="10,0">
                                <TextBlock Text="{Binding Path=Name}" HorizontalAlignment="Stretch" VerticalAlignment="Center" Style="{StaticResource TextFontStyleTextBlock}" FontSize="14" TextTrimming="CharacterEllipsis" />
                                <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding Path=Time,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" Style="{StaticResource LabelFontStyleTextBlock}"  TextTrimming="CharacterEllipsis" FontSize="12" Margin="5,0,0,0"/>
                            </StackPanel>

                            <ProgressBar Grid.Row="1" Height="10" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="10,0,10,0" Value="{Binding Percentage, Mode=OneWay, Converter={StaticResource doubleToProgress}}">
                                <ProgressBar.Foreground>
                                    <MultiBinding Converter="{StaticResource ProgressBarColorConverter}">
                                        <Binding Mode="OneWay" Path="Percentage" />
                                        <Binding Mode="OneWay" Path="IsStatic" />
                                    </MultiBinding>
                                </ProgressBar.Foreground>
                            </ProgressBar>

                            <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10,0,10,0">
                                <Image VerticalAlignment="Center" Visibility="{Binding IsStatic, Converter={StaticResource CollapsedIfFalse}, Mode=OneWay, FallbackValue=Collapsed}" Source="/Common;component/Images/alert.ico" Margin="2,2,2,2"
                                                    RenderOptions.BitmapScalingMode="HighQuality"
                                                   RenderOptions.EdgeMode="Aliased" />
                                <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding Path=Description,Mode=OneWay}" Foreground="Gray" TextTrimming="CharacterEllipsis" FontSize="11"/>
                            </StackPanel>
                        </Grid>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
<ListBox Grid.Row="0" x:Name="items" ItemsSource="{Binding Path=MyCollection}"
                                 ItemContainerStyle="{StaticResource CollectionStyle}"   />
 

Есть ли способ исправить это замораживание? Наличие фиксированной высоты в списке не является приемлемым результатом, поскольку это приводит к появлению вертикальной полосы прокрутки в элементе управления, который уже имеет вертикальную полосу прокрутки

Ответ №1:

Наличие фиксированной высоты в списке не является приемлемым результатом, поскольку это приводит к появлению вертикальной полосы прокрутки в элементе управления, который уже имеет вертикальную полосу прокрутки

Мне это кажется подозрительным. Когда непосредственная родительская панель ListBox не Grid является or DockPanel (где ее последним дочерним элементом является ListBox with LastChildFill=true ), listbox теряет свою виртуализацию и прокрутку. Поскольку виртуализация теряется, listbox де-виртуализирует все строки и при этом зависает поток пользовательского интерфейса.

Вы ListBox завернуты в какой-то просмотрщик прокрутки? К сожалению, если это так, вам придется либо пропустить средство просмотра прокрутки, либо применить фиксированный размер к ListBox .

Если вы хотите, чтобы поле списка auto-occupy занимало оставшееся пространство контейнера, выполните некоторую привязку к фактической высоте родительской панели ptoperty с помощью некоторого конвертера и «вычислите», необходимые Height для ListBox в этом конвертере. Таким образом, это будет выглядеть так, как будто список занимает все пространство, но на самом деле был применен с некоторой фиксированной высотой через привязку.

Но это может быть сложно в зависимости от ситуации!