#vb.net #list #linq-to-objects
#vb.net #Список #linq-to-objects
Вопрос:
Я нашел код для реализации SortableBindingList, который расширяет BindingList, и теоретически он позволяет сортировать и фильтровать список общих объектов. Он отлично работает, сортируя список, но я не могу получить фильтрацию.
Код фильтра выглядит следующим образом
Protected Sub UpdateFilter()
_isSorted = False 'remove sort.
Try
'We filter on the entire collection
Dim filtered = _originalData.AsQueryable()
If Not String.IsNullOrEmpty(_filter) Then filtered = filtered.Where(_filter)
Dim filteredResult = filtered.ToList()
Items.Clear()
If filteredResult IsNot Nothing AndAlso filteredResult.Count > 0 Then
For Each tItem As T In filtered
Items.Add(tItem)
Next
End If
Catch
'Reset the list
Items.Clear()
For Each tItem As T In _originalData
Items.Add(tItem)
Next
'Rethrow the error
Throw
Finally
OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End Try
End Sub
Проблема в том, что следующий пример получает как фильтр строку в предложении where, но компиляция выдает ошибку, поскольку она ожидает функцию
Я не знаю, как это решить
Извините, если вы плохо понимаете. Я плохо говорю по-английски
Комментарии:
1.
Where
Предложение ожидаетFunction(item as T)
(где T — тип элементов в_originalData
), который возвращаетBoolean
результат. Вам понадобится функция, которая может анализировать_filter
и обрабатывать логику, которую она представляет, доBoolean
результата. Это непростая задача. Более простой способ (но все же требующий значительного объема работы) — предоставить пользователю форму, которая позволяет ему выбрать свойство, определенное наT
, применить оператор сравнения и ввести значение для сравнения свойства. Выполнение этого таким образом ограничивает возможности, которые необходимо учитывать в коде вычисления выражения.2. Продолжение.. Если вы знакомы с MS Excel, посмотрите, как они обрабатывают определение пользовательского автофильтра, представляя диалоговое окно с выпадающими списками.
Ответ №1:
Вам нужно передать предикат. Я надеюсь, что этот пример поможет вам.
Private Function AddFilter(list As List(Of String), filter As Func(Of String, Integer, Boolean)) As List(Of String)
Dim l As IEnumerable(Of String) = Nothing
If Not IsNothing(filter) Then
l = list.Where(filter)
End If
Return l.ToList
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim A As New List(Of String) From {"Mathew", "Mark", "Luke", "John"}
Dim predicate As Func(Of String, Integer, Boolean) = Function(str, index) str.StartsWith("M")
Dim FilteredList = AddFilter(A, predicate)
For Each s As String In FilteredList
Debug.Print(s)
Next
End Sub
Ответ №2:
В каком-то сообщении есть ответ, который рекомендует это.
Вы можете использовать динамический Linq:
Затемняйте фильтр как String = «property1>10 и property2 как ‘anystring’ или property3<=25».
Тусклые результаты = элементы.Где(фильтр).
Но я не знаю, как использовать dinamic linq