使用第二个绑定列表类通过文本框过滤列表datagridview并设置为vb.net中的bingingsource.datasource

问题描述 投票:0回答:1

我正在尝试使用第二个绑定列表类通过文本框过滤列表 datagridview 并设置为 vb.net 中的 bindingsource.datasource 。

问题是,当我过滤两个事件文本框,然后在其中一个文本框中清除或空白时,datagridview 的状态不处于过滤器中的状态。

带绑定列表的结果过滤器

应该是当我清除文本框 criteria2 时,datagridview 应保持引用文本框 criteria1 的过滤器状态,如下图所示,应将过滤器保留在 criteria1

A

我的代码有问题吗?

类 SortableBindingList

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel


''' <summary>
''' Provides a generic collection that supports data binding and additionally supports sorting.
''' See http://msdn.microsoft.com/en-us/library/ms993236.aspx
''' If the elements are IComparable it uses that; otherwise compares the ToString()
''' </summary>
''' <typeparam name="T">The type of elements in the list.</typeparam>
Public Class SortableBindingList(Of T As Class)
        Inherits BindingList(Of T)

        Private _isSorted As Boolean
        Private _sortDirection As ListSortDirection = ListSortDirection.Ascending
        Private _sortProperty As PropertyDescriptor

        ''' <summary>
        ''' Initializes a new instance of the <see cref="SortableBindingList{T}"/> class.
        ''' </summary>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' Initializes a new instance of the <see cref="SortableBindingList{T}"/> class.
        ''' </summary>
        ''' <param name="list">An <see cref="T:System.Collections.Generic.IList`1" /> of items to be contained in the <see cref="T:System.ComponentModel.BindingList`1" />.</param>
        Public Sub New(ByVal list As IList(Of T))
            MyBase.New(list)
        End Sub

        ''' <summary>
        ''' Gets a value indicating whether the list supports sorting.
        ''' </summary>
        Protected Overrides ReadOnly Property SupportsSortingCore As Boolean
            Get
                Return True
            End Get
        End Property

        ''' <summary>
        ''' Gets a value indicating whether the list is sorted.
        ''' </summary>
        Protected Overrides ReadOnly Property IsSortedCore As Boolean
            Get
                Return _isSorted
            End Get
        End Property

        ''' <summary>
        ''' Gets the direction the list is sorted.
        ''' </summary>
        Protected Overrides ReadOnly Property SortDirectionCore As ListSortDirection
            Get
                Return _sortDirection
            End Get
        End Property

        ''' <summary>
        ''' Gets the property descriptor that is used for sorting the list if sorting is implemented in a derived class; otherwise, returns null
        ''' </summary>
        Protected Overrides ReadOnly Property SortPropertyCore As PropertyDescriptor
            Get
                Return _sortProperty
            End Get
        End Property

        ''' <summary>
        ''' Removes any sort applied with ApplySortCore if sorting is implemented
        ''' </summary>
        Protected Overrides Sub RemoveSortCore()
            _sortDirection = ListSortDirection.Ascending
            _sortProperty = Nothing
            _isSorted = False
        End Sub

    ''' <summary>
    ''' Sorts the items if overridden in a derived class
    ''' </summary>
    ''' <param name="prop"></param>
    ''' <param name="direction"></param>
    Protected Overrides Sub ApplySortCore(ByVal prop As PropertyDescriptor, ByVal direction As ListSortDirection)
        _sortProperty = prop
        _sortDirection = direction

        Dim list As List(Of T) = TryCast(Items, List(Of T))
        If list Is Nothing Then
            Return
        End If

        list.Sort(AddressOf Compare)

        _isSorted = True
        'fire an event that the list has been changed.
        OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
    End Sub
    Private Function Compare(ByVal lhs As T, ByVal rhs As T) As Integer
            Dim result = OnComparison(lhs, rhs)
            'invert if descending
            If _sortDirection = ListSortDirection.Descending Then
                result = -result
            End If
            Return result
        End Function

        Private Function OnComparison(ByVal lhs As T, ByVal rhs As T) As Integer
            Dim lhsValue As Object = If(lhs Is Nothing, Nothing, _sortProperty.GetValue(lhs))
            Dim rhsValue As Object = If(rhs Is Nothing, Nothing, _sortProperty.GetValue(rhs))
            If lhsValue Is Nothing Then
                Return If(rhsValue Is Nothing, 0, -1) 'nulls are equal
            End If
            If rhsValue Is Nothing Then
                Return 1 'first has value, second doesn't
            End If
            If TypeOf lhsValue Is IComparable Then
                Return DirectCast(lhsValue, IComparable).CompareTo(rhsValue)
            End If
            If lhsValue.Equals(rhsValue) Then
                Return 0 'both are the same
            End If
            'not comparable, compare ToString
            Return lhsValue.ToString().CompareTo(rhsValue.ToString())
        End Function
    End Class

Public Class Form4
    Private StockCardsCache As List(Of StockCards)
    Private _criteriasBindingList As New SortableBindingList(Of StockCards)()
    Private bindingSource As BindingSource = Nothing
    Private Sub LoadData()
        StockCardsCache = New List(Of StockCards) From {
            New StockCards() With {
                .Invono = "PI0001",
                .InvoDate = New DateTime(2024, 2, 1),
                .Transaction = "PURCHASE",
                .CodeProduct = "TEST 1000",
                .Barcode = "1000",
                .Criteria1 = "A",
                .Criteria2 = "C",
                .Criteria3 = "E",
                .Criteria4 = "G",
                .IN = 10,
                .OUT = 0,
                .BLC = 10
            },
            New StockCards() With {
                .Invono = "PI0001",
                .InvoDate = New DateTime(2024, 2, 1),
                .Transaction = "PURCHASE",
                .CodeProduct = "TEST 1000",
                .Barcode = "1000",
                .Criteria1 = "B",
                .Criteria2 = "D",
                .Criteria3 = "F",
                .Criteria4 = "H",
                .IN = 12,
                .OUT = 0,
                .BLC = 22
            },
            New StockCards() With {
                .Invono = "PI0001",
                .InvoDate = New DateTime(2024, 2, 1),
                .Transaction = "PURCHASE",
                .CodeProduct = "TEST 1000",
                .Barcode = "1000",
                .Criteria1 = "A",
                .Criteria2 = "E",
                .Criteria3 = "G",
                .Criteria4 = "I",
                .IN = 12,
                .OUT = 0,
                .BLC = 34
            },
            New StockCards() With {
                .Invono = "PI0001",
                .InvoDate = New DateTime(2024, 2, 1),
                .Transaction = "PURCHASE",
                .CodeProduct = "TEST 1000",
                .Barcode = "1000",
                .Criteria1 = "B",
                .Criteria2 = "F",
                .Criteria3 = "H",
                .Criteria4 = "J",
                .IN = 12,
                .OUT = 0,
                .BLC = 46
            }
        }
        _criteriasBindingList = New SortableBindingList(Of StockCards)(StockCardsCache)
        bindingSource = New BindingSource With {.DataSource = _criteriasBindingList}
        DataGridView1.DataSource = bindingSource
    End Sub
    Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        LoadData()
    End Sub

    Private Sub txtcriteria1_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria1.TextChanged
        Dim str = txtcriteria1.Text.Trim().ToLower()
        bindingSource.DataSource = If(String.IsNullOrEmpty(str), _criteriasBindingList, _criteriasBindingList.Where(Function(c) c.Criteria1.ToLower().Contains(str)).ToList())
    End Sub
    Private Sub txtcriteria2_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria2.TextChanged
        Dim str = txtcriteria2.Text.Trim().ToLower()
        bindingSource.DataSource = If(String.IsNullOrEmpty(str), _criteriasBindingList, _criteriasBindingList.Where(Function(c) c.Criteria2.ToLower().Contains(str)).ToList())
    End Sub
End Class
vb.net datagridview ienumerable bindingsource bindinglist
1个回答
2
投票

您的代码

    Private Sub txtcriteria1_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria1.TextChanged
        Dim str = txtcriteria1.Text.Trim().ToLower()
        bindingSource.DataSource = If(String.IsNullOrEmpty(str), _criteriasBindingList, _criteriasBindingList.Where(Function(c) c.Criteria1.ToLower().Contains(str)).ToList())
    End Sub
    Private Sub txtcriteria2_TextChanged(sender As Object, e As EventArgs) Handles txtcriteria2.TextChanged
        Dim str = txtcriteria2.Text.Trim().ToLower()
        bindingSource.DataSource = If(String.IsNullOrEmpty(str), _criteriasBindingList, _criteriasBindingList.Where(Function(c) c.Criteria2.ToLower().Contains(str)).ToList())
    End Sub

执行以下操作:

  • 如果您更改第一个标准
    • 如果它为空或为空,那么你就可以避免过滤
    • 否则您仅按此条件过滤
  • 如果您更改第二个标准
    • 如果它为空或为空,那么你就可以避免过滤
    • 否则您仅按此条件过滤

相反,实现一个过滤功能,例如:

Private Sub myFilter(str1 As String, str2 As String)
    If (String.IsNullOrEmpty(str1) AndAlso String.IsNullOrEmpty(str2)) Then
        bindingSource.DataSource = _criteriasBindingList
    Else If (String.IsNullOrEmpty(str1)) Then
        bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.Criteria2.ToLower().Contains(str2)).ToList()
    Else If (String.IsNullOrEmpty(str2)) Then
        bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.Criteria1.ToLower().Contains(str1)).ToList()
    Else
       bindingSource.DataSource = _criteriasBindingList.Where(Function(c) c.Criteria1.ToLower().Contains(str1) AndAlso c.Criteria2.ToLower().Contains(str2)).ToList()
    End If
End Sub

总而言之,您需要应用每一个适用的标准。

© www.soinside.com 2019 - 2024. All rights reserved.