【问题标题】:Why does adding a <Browsable(False)> attribute to a class property prevent FilterItemOnProperty() from properly retrieving the property's value?为什么向类属性添加 <Browsable(False)> 属性会阻止 FilterItemOnProperty() 正确检索属性的值?
【发布时间】:2026-02-24 12:25:01
【问题描述】:

我编写了一个继承自 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”。

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

问题是,为什么将&lt;Browsable(False)&gt; 属性添加到类属性会阻止FilterItemOnProperty() 正确检索该属性的值?

【问题讨论】:

  • 您是否尝试过编写一个简单的测试应用程序来验证是否是 BrowsableAttribute 导致了问题?也许还有其他您不知道或忘记的修改。
  • 我还没有创建一个测试应用程序,但这是在代码昨天工作和今天不工作之间提交到源代码控制存储库的仅有的两个更改之一(另一个更改提交的是不相关的代码部分)。我通过从属性中删除BrowsableAttribute 进一步验证了它,代码再次运行。

标签: .net vb.net winforms combobox browsable


【解决方案1】:

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

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

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

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

如果您有多个具有&lt;Browsable(False)&gt; 属性的类,在ComboBox 中用作ValueMemeber,您需要考虑使用属性的名称,也许您可​​以将所有这些都命名为“ID”。

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

【讨论】: