如何基于未知属性过滤对象列表

时间:2016-08-20 19:01:59

标签: vb.net linq datagrid user-controls

我创建了一个由文本框和数据网格组成的用户控件。 (代码未包含在下面的示例中)。 我需要通过特定列过滤数据网格的内容。 列的名称取决于对象属性的名称。 对象会有所不同,但每个控件都将绑定到特定对象。

我如何使用控件示例:

Public Class Form1

    Private ObjectList As List(Of Object)
    Sub New()
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        ObjectList = GenerateRandomData()
        AddHandler Me.MyUserControl.SelectionStatusChanged, AddressOf UpdateForm
        AddHandler Me.MyUserControl.TextChanged, AddressOf UpdateList

        Me.MyUserControl.DataSource = ObjectList
    End Sub

    Private Sub UpdateList()
        Dim FilteredList As IEnumerable(Of Object) = From obj As Item In ObjectList
                                                     Where obj.Prop_1.StartsWith(Me.MyUserControl.Text)
                                                     Select obj
        Me.MyUserControl.DataSource = FilteredList.ToList
    End Sub

    Private Sub UpdateForm()
        If Me.MyUserControl.HasItemLoaded Then
            Dim NewItem As Item = CType(Me.MyUserControl.SelectedItem, Item)
            TextBox1.Text = NewItem.Prop_1
            TextBox2.Text = NewItem.Prop_2
            TextBox3.Text = NewItem.Prop_3
            Return
        End If
        TextBox1.Text = ""
        TextBox2.Text = ""
        TextBox3.Text = ""
    End Sub

    Private Function GenerateRandomData() As List(Of Object)
        Randomize()
        Dim lst As New List(Of Object)
        For i = 0 To 10000
            Dim itm As New Item
            Dim value As Integer = CInt(Int((999999 * Rnd()) + 1))
            Dim value2 As Integer = CInt(Int((999999 * Rnd()) + 1))
            itm.Prop_1 = value
            itm.Prop_2 = "abc " & value & value2
            itm.Prop_3 = value2 & value & " abc"
            lst.Add(itm)
        Next
        Return lst
    End Function
End Class

我想在User控件中处理UpdateList()的工作(移动代码或等效结果),但问题是控件不知道对象类型,所以我不能直接调用Prop_1或者其他什么名字用户控件内的属性。

到目前为止,我通过监听用户控件之外的事件来完成此操作,但我希望从程序员那里删除尽可能多的责任。

欢迎任何想法。

1 个答案:

答案 0 :(得分:2)

以下是围绕其SetList方法设计的,该方法用于设置源列表(IEnumerable(Of T))以及要在UpDateList方法中过滤的属性的名称。它使用Reflection来检索所需的属性。

Public Class UserControl1
    Private list As IEnumerable
    Private filterPropInfo As Reflection.PropertyInfo

    Public Sub SetList(Of T)(list As IEnumerable(Of T), filterPropertyName As String)
        filterPropInfo = GetType(T).GetProperty(filterPropertyName, GetType(String))
        If filterPropInfo Is Nothing Then
            Throw New ArgumentException(String.Format("{0} is not a Public String Property on Type: {1}", filterPropertyName, GetType(T).FullName))
        End If
        Me.list = list
    End Sub

    Public Sub UpdateList()
        Dim FilteredList As IEnumerable(Of Object) = From obj In list
                                                     Where CStr(filterPropInfo.GetValue(obj)).StartsWith(Me.Text)
                                                     Select obj

        Me.DataGridView1.DataSource = FilteredList.ToList
    End Sub
End Class

通过调用test方法使用示例。

Public Class Form1
    Sub test()
        Dim l As New List(Of Item)
        l.Add(New Item("fred"))
        l.Add(New Item("freddy"))
        l.Add(New Item("fredrick"))
        l.Add(New Item("joe"))
        UserControl11.[Text] = "fred"
        UserControl11.SetList(l, "Field1")
        UserControl11.UpdateList()
    End Sub
End Class

Class Item
    Public Property Field1 As String
    Public Property Field2 As Int32
    Public Sub New(f1 As String)
        Me.Field1 = f1
    End Sub
End Class