2016-08-20 10 views
1

テキストボックスとデータグリッドからなるユーザーコントロールを作成しました。 (コードは以下のサンプルに含まれていません)。 データグリッドの内容を特定の列でフィルタリングする必要があります。 列の名前は、オブジェクトのプロパティの名前によって異なります。 オブジェクトはさまざまですが、各コントロールは特定のオブジェクトにバインドされます。不明なプロパティに基づいてオブジェクトリストをフィルタリングする方法

私は制御例使用していますどのように:私はUpdateList(の仕事を処理したい

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 

)をユーザーコントロール内(コードまたは同等の結果を移動)が、問題はコントロールがあるということです私はProp_1を直接呼び出すことはできませんし、ユーザーコントロール内のプロパティの名前は何でも構いません。

これまで私はユーザーコントロールの外のイベントをリッスンすることでこれを達成しましたが、プログラマから多くの責任を取り除きたいと思います。

アイデアを歓迎します。

答えて

2

以下は、UpDateListメソッドでソースリスト(IEnumerable(Of T))とフィルタリングするプロパティの名前を設定するために使用されるSetListメソッドの周りに設計されています。 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 
+0

ありがとうございます。 Reflectionを使用するソリューションは、まさに私が探していたものでした。 –

関連する問題