2016-08-20 56 views
1

我創建了一個由文本框和數據網格組成的用戶控件。 (代碼不包括在下面的示例中)。 我需要按特定列過濾數據網格的內容。 列的名稱取決於對象屬性的名稱。 該對象會有所不同,但每個控件都將綁定到特定對象。如何根據未知屬性過濾對象列表

我如何使用控制例如:

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 

我想處理UpdateList()的用戶控件內的工作(移動代碼或等效的結果),但問題是,控制不知道對象類型,所以我不能直接調用Prop_1或任何是用戶控件內的屬性名稱。

到目前爲止,我通過監聽用戶控件之外的事件來完成此任務,但我希望從程序員中刪除儘可能多的責任。

歡迎任何想法。

回答

2

以下是圍繞其SetList方法設計的,用於設置源列表(IEnumerable(Of T))和在UpDateList方法中過濾的屬性的名稱。它使用反射來檢索所需的屬性。

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 
+0

謝謝。使用Reflection的解決方案正是我所期待的。 –

相關問題