Быстрая и эффективная фильтрация списка, привязанного к коллекции в ViewModel - PullRequest
1 голос
/ 06 марта 2012

В моем окне wpf у меня есть два списка.Один для доступных предметов, а другой для выбранных предметов.Доступные предметы обычно содержат 3000+ предметов, если не отфильтрованы.Пользователю предоставляется поле со списком для фильтрации по типу элемента и текстовое поле для фильтрации по имени элемента.В настоящее время я использую Linq для фильтрации элементов, но список обновляется очень медленно.Мне интересно, есть ли лучший подход.

Некоторые примечания, представляющие интерес: я создал прикрепленное поведение, чтобы позволить мне привязывать свойство selecteditems (обратите внимание на 's') к модели представления и этому поведениютребуется тип коллекции для работы.У меня установлен текстовый фильтр для обновления свойства при его изменении, и в установщике свойств я вызываю метод фильтра.

Просмотр:

<DatePicker Grid.Row="0" Grid.Column="1" Height="26" VerticalAlignment="Center" SelectedDate="{Binding FromDate}" />
<DatePicker Grid.Row="0" Grid.Column="3" Height="26" VerticalAlignment="Center" SelectedDate="{Binding ToDate}" />
<ComboBox Grid.Row="1" Grid.Column="1"  Height="22" VerticalAlignment="Center" ItemsSource="{Binding Classes}" SelectedItem="{Binding SelectedClass}" />
<TextBox Grid.Row="4" Grid.Column="1" Height="22" VerticalAlignment="Center" Text="{Binding CiNameFilterText, UpdateSourceTrigger=PropertyChanged}" Margin="55,0,0,178" />
<ListBox Grid.Row="4" Grid.Column="1" Height="172" ItemsSource="{Binding AvailableCis}" DisplayMemberPath="CiName" SelectionMode="Extended" Ocean_WPF:ListBoxBehavior.SelectedItems="{Binding AvailableCisSelected}" Margin="0,28,0,0" />
<ListBox Grid.Row="4" Grid.Column="3" Height="200" ItemsSource="{Binding SelectedCis}" DisplayMemberPath="CiName" SelectionMode="Extended" Ocean_WPF:ListBoxBehavior.SelectedItems="{Binding SelectedCisSelected}" />

ViewModel:

Protected Sub FilterCiList()
    Try
        If (_caCiData IsNot Nothing) Then
            If ((_selectedClass IsNot Nothing AndAlso Not _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText IsNot Nothing AndAlso Not _ciNameFilterText.Equals(String.Empty))) Then
                Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.Class.ToUpper.Equals(_selectedClass.ToUpper) AndAlso ci.CiName.ToUpper.Contains(_ciNameFilterText.ToUpper)).OrderBy(Function(a) a.CiName))
            ElseIf ((_selectedClass IsNot Nothing AndAlso Not _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText Is Nothing OrElse _ciNameFilterText.Equals(String.Empty))) Then
                Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.Class.ToUpper.Equals(_selectedClass.ToUpper)).OrderBy(Function(a) a.CiName))
            ElseIf ((_selectedClass Is Nothing OrElse _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText IsNot Nothing AndAlso Not _ciNameFilterText.Equals(String.Empty))) Then
                Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.CiName.ToUpper.Contains(_ciNameFilterText.ToUpper)).OrderBy(Function(a) a.CiName))
            Else
                Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.OrderBy(Function(a) a.CiName))
            End If

            If (Me.SelectedCis IsNot Nothing) Then
                For Each Ci In Me.SelectedCis
                    Me.AvailableCis.Remove(Ci)
                Next
            End If
        End If
    Catch ex As Exception
        _viewModelUIService.ExceptionDialog(ex)
    End Try
End Sub

_caCiData - полный нефильтрованный список.Если я отфильтрую список, мне нужно отобразить только те элементы, которые соответствуют фильтру, поэтому я просто добавляю эти элементы в свойство AvailableCis с помощью запроса Linq.

Должен быть лучший способ сделать это в качестве фильтрацииработает медленно (занимает около 5 секунд, прежде чем он сможет обновить список в представлении)

Редактировать: мой друг предложил просмотр данных, будет ли это работать лучше, чем фильтровать всю коллекцию каждый раз?

1 Ответ

0 голосов
/ 06 марта 2012

Я понял это. Тот же друг, который предложил Dataview, только что вспомнил, что есть ошибка с WPF и загрузкой его слишком большим количеством элементов. Это действительно замедлило пользовательский интерфейс. Я изменил списки на Datagrids и стилизовал их так, чтобы они выглядели как списки. Результат был днем ​​и ночью. У меня есть скорость, которую я хочу сейчас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...