vb.net - 如何为数据绑定自定义组合框获取第二个 ValueMember
问题描述
我有一个简单的自定义组合框,它只添加了一个属性“ValueMember2”。
我已将组合框数据源添加到数据集
我可以像设置普通属性“ValueMember”一样在代码中设置属性
cboRadioType.ValueMember = "ID"
cboRadioType.ValueMember2 = "FREQMIN"
cboRadioType.DisplayMember = "MODEL"
正常的 ValueMember 属性将返回来自数据源的 ID 新的 ValueMember2 属性只返回字符串“FREQMIN”
我的自定义组合框代码如下:
Imports System.ComponentModel
Public Class NewCBO
Inherits ComboBox
Dim vm2 As String
<Description("Gets/Sets the ValueMember2 of Control")>
Property ValueMember2() As String
Get
ValueMember2 = vm2
End Get
Set(ByVal Value As String)
vm2 = Value
End Set
End Property
End Class
我需要更改我的自定义属性以使其从连接的数据源返回值?所有搜索都出现了如何“显示ValueMember”
解决方案
这是一个自定义ComboBox
类,其中包括一个相当严格的实现,ValueMember2
并SelectedValue2
基于现有的ValueMember
and实现SelectedValue
:
Imports System.ComponentModel
Public Class ComboBoxEx
Inherits ComboBox
Private _valueMember2 As BindingMemberInfo
Public Property ValueMember2 As String
Get
Return _valueMember2.BindingMember
End Get
Set(value As String)
If value Is Nothing Then
value = String.Empty
End If
Dim bindingMemberInfo As New BindingMemberInfo(value)
If bindingMemberInfo.Equals(_valueMember2) Then
Return
End If
'This part is implemented in ValueMember but cannot be here because SetDataConnection is Private.
'It may be possible to provide our own implement of SetDataConnection but that is not done here.
'If DisplayMember.Length = 0 Then
' SetDataConnection(DataSource, bindingMemberInfo, False)
'End If
'This part is implemented in ValueMember but cannot be here because BindingMemberInfoInDataManager is Private.
'It may be possible to provide our own implement of BindingMemberInfoInDataManager but that is not done here.
'If DataManager IsNot Nothing AndAlso
' value <> String.Empty AndAlso
' Not BindingMemberInfoInDataManager(bindingMemberInfo) Then
' Throw New ArgumentException("...", NameOf(value))
'End If
_valueMember2 = bindingMemberInfo
'A rigorous implementation should also include implementation of corresponding events.
'OnValueMember2Changed(EventArgs.Empty)
'OnSelectedValue2Changed(EventArgs.Empty)
End Set
End Property
Public Property SelectedValue2 As Object
Get
Return If(SelectedIndex <> -1 AndAlso DataManager IsNot Nothing,
FilterItemOnProperty(DataManager.List(SelectedIndex), _valueMember2.BindingField),
Nothing)
End Get
Set(value As Object)
If DataManager Is Nothing Then
Return
End If
Dim bindingField = _valueMember2.BindingField
If String.IsNullOrEmpty(bindingField) Then
Throw New InvalidOperationException("...")
End If
'This part is implemented in ValueMember but cannot be here because DataManager.Find is Private.
'SelectedIndex = DataManager.Find(DataManager.GetItemProperties().Find(bindingField, True), value, True)
'The following replaces the call to DataManager.Find above.
If value Is Nothing Then
Throw New ArgumentNullException(NameOf(value))
End If
Dim newSelectedIndex = -1
Dim [property] = DataManager.GetItemProperties().Find(bindingField, True)
If [property] IsNot Nothing Then
Dim list=DataManager.List
Dim bindingList = TryCast(list, IBindingList)
If bindingList?.SupportsSearching Then
newSelectedIndex = bindingList.Find([property], value)
Else
For i = 0 To list.Count - 1
Dim obj = list(i)
If value.Equals(obj) Then
newSelectedIndex = i
Exit For
End If
Next
End If
End If
SelectedIndex = newSelectedIndex
End Set
End Property
End Class
里面有一些你应该阅读的笔记。另请注意,缺少ValueMember
设计时支持。ValueMember2
使用同一个编辑器可能并不难,但我没有研究过。还值得注意的是ValueMember
andSelectedValue
被实现ListControl
,因此也被继承ListBox
。您必须在自定义中单独实现此代码ListBox
。
我使用以下代码测试了该控件:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
With table.Columns
.Add("Id", GetType(Integer))
.Add("Name", GetType(String))
.Add("DateOfBirth", GetType(Date))
End With
With table.Rows
.Add(1, "Peter", #1/1/2001#)
.Add(2, "Paul", #2/2/2002#)
.Add(3, "Mary", #3/3/2003#)
End With
BindingSource1.DataSource = table
With ComboBoxEx1
.DisplayMember = "Name"
.ValueMember = "Id"
.ValueMember2 = "DateOfBirth"
.DataSource = BindingSource1
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MessageBox.Show($"ID: {ComboBoxEx1.SelectedValue}; Date of Birth: {ComboBoxEx1.SelectedValue2}", ComboBoxEx1.Text)
End Sub
End Class
它完全按预期工作。相同的代码也应该适用于其他数据源,例如 a List(Of T)
,尽管我没有做任何额外的测试。
推荐阅读
- javascript - 使用空白单元格以编程方式排序
- macos - macOS 11 启动代理无法访问 NFS 共享
- python - 我试图将一个字符串类型转换为一个 int 并且它给了我一个值错误,但只有当它在循环中时我才定义它
- flutter - 如何在 Dio Flutter 中传递密码和用户名加密?
- strapi - 如何在 Strapi 中搜索多个关键字?
- python - 如何在python中对条件字符串进行df转换?
- elasticsearch - 过滤在 Kibana 内彼此相隔 X 分钟内发生的事件
- esp8266 - 从 Azure IoT Hub 到 ESP8266 的云到设备 (C2D) 消息 - 通过 Azure CLI 但不通过 HTTP 请求工作
- javascript - 为什么我的 Github 密码失败(每次事件都更改)?
- android - XML中的问号作为值