Почему добавление атрибута <Browsable (False)> к свойству класса не позволяет FilterItemOnProperty() правильно получить значение свойства?

Я написал собственный элемент управления ComboBox, который наследуется от System.Windows.Forms.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

По сути, чтение значения вернет 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

Свойство ModalityID, которое используется в качестве ValueMember ComboBox, имеет добавленный атрибут Browsable(False), поэтому он не отображается в виде столбца, когда коллекция объектов Modality привязывается к элементу управления DataGridView в другом месте приложения.

Это теперь ломает приложение, потому что MyComboBox1.Value теперь возвращает выбранный объект Modality, а не ModalityID выбранного объекта Modality, даже если ValueMember ComboBox по-прежнему установлен в "ModalityID".

Копаться в исходном коде.NET Framework для ListControl.FilterItemOnProperty(object item, string field) не просветляет меня.

Вопрос в том, почему добавление <Browsable(False)> приписать свойство класса предотвратить FilterItemOnProperty() от правильного получения значения свойства?

1 ответ

Из параметров метода ListControl.FilterItemOnProperty Method (Object, String) вы можете видеть, что имя свойства идет туда в виде строки (заданной из значения ValueMemeber).

И я не использовал Reflector, но думаю, что внутри метода был создан список свойств объекта и я пытался найти данное PropertyName в виде строки.

Очевидно создание списка, независящего от BrowsableAttribute. А если для атрибута установлено значение False, свойство не попадет в список и не может быть найдено.

Так что если это <Browsable(False)> свойство только в одном классе, то в коде, где вы читаете SelectedValueПрочитайте MobalityID от выбранного объекта.

Если у вас есть умножить классы с <Browsable(False)> свойства, которые используются в качестве ValueMemeber в ComboBox вам нужно подумать об именах используемых свойств, может быть, вы можете назвать все из них просто "ID", например.

Если это возможно, создайте Inerface, который имеет только одно свойство.ID, и внедрите его во все ваши классы Browsable(False), а затем создайте универсальное свойство Value для классов с этим интерфейсом. Тогда вы можете получить свойство ID прямо из кода.

Другие вопросы по тегам