0

我编写了一个继承自 System.Windows.Forms.ComboBox 的自定义 ComboBox 控件。它有一个“值”属性,我写如下:

Public Property Value() As Object
    Get
        If SelectedIndex = -1 Then Return Nothing
        If String.IsNullOrWhitespace(ValueMember) Then
            Return Items(SelectedIndex)
        Else
            Return FilterItemOnProperty(Items(SelectedIndex), ValueMember)
        End If
    End Get
    Set(ByVal newvalue As Object)
        '...
    End Set
End Property

基本上,如果未选择任何内容,则读取 Value 将返回Nothing,如果未设置 ValueMember,则返回所选对象本身,如果设置了 ValueMember,则返回所选对象的适当属性值。

到目前为止,代码运行良好。

但是,最近对用于填充 ComboBox 的类之一进行了如下更改:

Partial Public Class Modality
    <Browsable(False)>
    Public Property ModalityID As Integer
    Public Property ModalityName As String
    Public Property ModalityAbbrevName As String
End Class

用作 ComboBox 的 ValueMember 的 ModalityID 属性已添加 Browsable(False) 属性,因此当 Modality 对象的集合绑定到应用程序中其他位置的 DataGridView 控件时,它不会显示为列。

现在这会破坏应用程序,因为 MyComboBox1.Value 现在返回选定的 Modality 对象,而不是选定 Modality 对象的 ModalityID,即使 ComboBox 的 ValueMember 仍设置为“ModalityID”。

深入研究 .NET Framework 的源代码ListControl.FilterItemOnProperty(object item, string field)并没有启发我。

问题是,为什么向<Browsable(False)>类属性添加属性会阻止FilterItemOnProperty()正确检索属性的值?

4

1 回答 1

1

从 ListControl.FilterItemOnProperty Method (Object, String) 方法的参数中,您可以看到属性名称以字符串形式出现(从 ValueMemeber 值给出)。

而且,我没有使用反射器,但认为在方法内部创建了一个对象属性列表并试图将给定的 PropertyName 作为字符串查找。

显然创建一个独立于 BrowsableAttribute 的列表。如果 Attribute 设置为 False 属性将不会列出并且无法找到。

因此,如果此<Browsable(False)>属性仅在一个类中,那么在您阅读的代码中SelectedValue,只需MobalityID从选定对象中读取一个。

如果您有多个具有使用的<Browsable(False)>属性的类ValueMemeberComboBox您需要考虑使用属性的名称,例如,也许您可​​以将所有这些命名为“ID”。

如果可以创建一个只有一个属性 .ID 的 Inerface 并将其实现到所有 Browsable(False) 类,然后为具有此接口的类创建通用 Value 属性。然后您可以直接从代码中获取 ID 的属性。

于 2013-03-16T07:35:37.240 回答