Почему добавление атрибута <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 прямо из кода.