我的程序中有一个bindingList,我想添加一些元素。元素是类 NameValue_Client 的一些实例,其中包含三个属性。我想使用我想要的任何属性搜索列表。
这是班级:
Public Class NameValue_Client
Implements INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private _assigned_db_name As String, _assigned_tcp_name As String
Private _val_obj As Client
Private _key_obj As Integer
Public WriteOnly Property DB_Name As String
Set(ByVal value As String)
_assigned_db_name = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("DB_Name"))
End Set
End Property
Public Property Value As Client
Get
Return _val_obj
End Get
Set(ByVal value As Client)
_val_obj = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Value"))
End Set
End Property
Public Property Key As Integer
Get
Return _key_obj
End Get
Set(ByVal value As Integer)
_key_obj = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Key"))
End Set
End Property
Public ReadOnly Property Name_Identifier As String
Get
Return String.Format("{0} : {1}", _assigned_db_name, _assigned_tcp_name)
End Get
End Property
Sub New(ByVal Key As Integer, ByVal DB_Name As String)
_assigned_db_name = DB_Name
_key_obj = Key
End Sub
Private Sub changed(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Handles Me.PropertyChanged
If e.PropertyName = "Value" Then
If _val_obj IsNot Nothing Then
_assigned_tcp_name = _val_obj.Details.Computer_Name
End If
End If
End Sub
Public Overrides Function ToString() As String
If _val_obj IsNot Nothing Then
Return String.Format("Db_Name:{0} Tcp_Name:{1} {2}", _assigned_db_name, _assigned_tcp_name, _val_obj.ToString)
Else
Return String.Format("Db_Name:{0} Tcp_Name:{1} Nothing", _assigned_db_name, _assigned_tcp_name)
End If
End Function
End Class
我在MSDN上找到了这个,它看起来是解决方案,但它只针对一个属性而且我不想放一个选择案例。它必须是一种更好的方式。
这是我找到的代码:
Public Class MyFontList
Inherits BindingList(Of Font)
Protected Overrides ReadOnly Property SupportsSearchingCore() As Boolean
Get
Return True
End Get
End Property
Protected Overrides Function FindCore(ByVal prop As PropertyDescriptor, _
ByVal key As Object) As Integer
' Ignore the prop value and search by family name.<--That's why
Dim i As Integer
While i < Count
If Items(i).FontFamily.Name.ToLower() = CStr(key).ToLower() Then
Return i
End If
i += 1
End While
Return -1
End Function
End Class
而且我不知道如何实施这个孩子&#39; class(从未使用过这种类型)。
这是我的代码(直到现在):
Public Class NameValue_Client
Implements INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private _assigned_db_name As String, _assigned_tcp_name As String
Private _val_obj As Client
Private _key_obj As Integer
Public WriteOnly Property DB_Name As String
Set(ByVal value As String)
_assigned_db_name = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("DB_Name"))
End Set
End Property
Public Property Value As Client
Get
Return _val_obj
End Get
Set(ByVal value As Client)
_val_obj = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Value"))
End Set
End Property
Public Property Key As Integer
Get
Return _key_obj
End Get
Set(ByVal value As Integer)
_key_obj = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Key"))
End Set
End Property
Public ReadOnly Property Name_Identifier As String
Get
Return String.Format("{0} : {1}", _assigned_db_name, _assigned_tcp_name)
End Get
End Property
Sub New(ByVal Key As Integer, ByVal DB_Name As String)
_assigned_db_name = DB_Name
_key_obj = Key
End Sub
Private Sub changed(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Handles Me.PropertyChanged
If e.PropertyName = "Value" Then
If _val_obj IsNot Nothing Then
_assigned_tcp_name = _val_obj.Details.Computer_Name
End If
End If
End Sub
Public Overrides Function ToString() As String
If _val_obj IsNot Nothing Then
Return String.Format("Db_Name:{0} Tcp_Name:{1} {2}", _assigned_db_name, _assigned_tcp_name, _val_obj.ToString)
Else
Return String.Format("Db_Name:{0} Tcp_Name:{1} Nothing", _assigned_db_name, _assigned_tcp_name)
End If
End Function
End Class
Public Class Interface_NameValue
Inherits BindingList(Of NameValue_Client)
Protected Overrides ReadOnly Property SupportsSearchingCore() As Boolean
Get
Return True
End Get
End Property
Protected Overrides Function FindCore(ByVal prop As PropertyDescriptor, _
ByVal key As Object) As Integer
' Ignore the prop value and search by family name.
Dim i As Integer
While i < Count
''Old-fashion way
Select Case prop.Name
Case "Value"
Case "Key"
Case "Name_Identifier"
End Select
i += 1
End While
Return -1
End Function
End Class
现在我应该怎么做这个新课程?我该如何实现呢?
答案 0 :(得分:1)
I want to search through the list using any property I want...and I don't want to put a select case .
来自MSDN的MyFontList
类显示了您将如何实现集合类 - 注意Inherits BindingList(Of Font)
- 而不是修改项< / em> class(NameValue_Client
)。您的代码将使用该类代替BindingList(of NameValue_Client)
集合变量。
有一种更简单的方法。
首先,虽然您的商品类没有理由订阅自己的PropertyChanged
事件。只需将Value
setter更改为:
Set(ByVal value As Client)
_val_obj = value
If _val_obj IsNot Nothing Then
_assigned_tcp_name = _val_obj.ComputerName
End If
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Value"))
End Set
在举起事件之前更新_assigned_tcp_name
将允许新的值对订阅该事件的任何内容可见,并且可能使用Name_Identifier
。但是你应该考虑摆脱_assigned_tcp_name
,因为它允许它变得过时&#34;陈旧&#34;:
Public ReadOnly Property Name_Identifier As String
Get
Dim tcpname = If(Value IsNot Nothing, Value.ComputerName, "")
Return String.Format("{0} : {1}", _assigned_db_name, tcpname)
End Get
End Property
KeyValuePair
类型的类似乎很奇怪,其中Value
基本上是可选的(显然是手动设置的)。它甚至根本不存在,因此可以Key
没有Value
。
在搜索方面,项目类中只有一个属性:Key
。 Value
是一种类型,这意味着您可能需要Client
上的任意数量的属性之一。 DB_Name
是WriteOnly(?!),因此无法搜索;我想你可能会搜索Name_Identifier
,但这是一个复合词,&#39; artificial&#39;属性。
我们只能在Client
上看到1个属性,所以我添加了一些用于说明目的:
Public Class Client
Public Property ComputerName As String
Public Property Foo As String
Public Property Bar As Int32
Public Sub New(n As String)
ComputerName = n
End Sub
End Class
您可以使用linq找到您想要的任何内容:
Dim Clients As New BindingList(Of NameValue_Client)
Dim c = New Client("ziggy") With {.Bar = 9, .Foo = "9"}
Dim NVC = New NameValue_Client(1, "Alpha")
NVC.Value = c
Clients.Add(NVC)
c = New Client("zoey") With {.Bar = 7, .Foo = "Q"}
NVC = New NameValue_Client(2, "Beta") With {.Value = c}
Clients.Add(NVC)
' find a key:
NVC = Clients.FirstOrDefault(Function(q) q.Key = 1)
' find a client object:
NVC = Clients.FirstOrDefault(Function(q) q.Value Is c)
' find a client.computername:
NVC = Clients.FirstOrDefault(Function(q) q.Value.ComputerName = "Mine")
' find a client.foo value
NVC = Clients.FirstOrDefault(Function(q) q.Value.Foo = "Q")
' return is Nothing if not found:
If NVC Is Nothing Then
' NOT FOUND!
Else
' found
Console.WriteLine(NVC.Name_Identifier)
End If
您搜索的内容可以是变量,但当然,搜索Key(int)需要int var,其他属性可能需要string
或DateTime
变量。
如上所述,如果无法找到您想要的内容,FirstOrDefault
将无效。如第二个示例中那样搜索Client
对象将要求c
与列表中的对象完全相同。即使具有相同属性值的其他客户端对象也不匹配。如果您需要,可以实现自己的比较器。
由于Value
可以是Nothing,任何涉及它的查询都应该考虑到这一点:
NVC = Clients.
FirstOrDefault(Function(q) q.Value IsNot Nothing AndAlso
q.Value.Foo = "Q")
项目类中的某些代码也应允许这样做,或者更改它以便在没有Client
对象的情况下无法创建项目。