Доступно только для чтения PropertyGrid

Мне нужно показать объект в PropertyGrid со следующими требованиями: объект и его подобъект должны быть доступны только для чтения, чтобы можно было активировать PropertyGrid CollectionEditors.

Я нашел образец, который полностью соответствует тому, что мне нужно, но есть неожиданное поведение, которое я не мог понять. У меня есть несколько PropertyGrids для разных объектов. В SetBrowsablePropertiesAsReadOnly я зацикливаю один объект, но на удивление все PropertyGrids в моем проекте становятся доступны только для чтения. Кто-нибудь может мне помочь. Вот код:



Imports System.Reflection
Imports System.ComponentModel

Public Class PropertyGridEx
    Inherits PropertyGrid

    Private isReadOnly As Boolean
    Public Property [ReadOnly]() As Boolean
        Get
            Return Me.isReadOnly
        End Get
        Set(ByVal value As Boolean)
            Me.isReadOnly = value
            Me.SetBrowsablePropertiesAsReadOnly(Me.SelectedObject, value)
        End Set
    End Property

    Protected Overloads Sub OnSelectedObjectsChanged(ByVal e As EventArgs)
        Me.SetBrowsablePropertiesAsReadOnly(Me.SelectedObject, Me.isReadOnly)
        MyBase.OnSelectedObjectsChanged(e)
    End Sub

    Private Sub SetBrowsablePropertiesAsReadOnly(ByRef selectedObject As Object, ByVal isReadOnly As Boolean)
        If selectedObject IsNot Nothing Then
            Dim props As PropertyDescriptorCollection = TypeDescriptor.GetProperties(selectedObject)
            For Each propDescript As PropertyDescriptor In props
                If propDescript.IsBrowsable AndAlso propDescript.PropertyType.GetInterface("ICollection", True) Is Nothing Then
                    Dim attr As ReadOnlyAttribute = TryCast(propDescript.Attributes(GetType(ReadOnlyAttribute)), ReadOnlyAttribute)
                    If attr IsNot Nothing Then
                        Dim field As FieldInfo = attr.[GetType]().GetField("isReadOnly", BindingFlags.NonPublic Or BindingFlags.Instance)
                        field.SetValue(attr, isReadOnly, BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, Nothing)
                    End If
                End If
            Next
        End If
    End Sub
End Class

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 396
2

Ответы 2

Атрибут ReadOnly устанавливается в определении класса, а не в экземпляре объекта. Следовательно, это повлияет на все экземпляры этого класса.

Чтобы добиться желаемого, создайте собственный PropertyDescriptor, в котором вы переопределите свойство IsReadOnly, и примените его к свойствам экземпляра вашего объекта.

Я уверен, что это неправильный синтаксис vb, но это можно сделать, добавив атрибут:

Private Sub SetBrowsablePropertiesAsReadOnly(ByRef selectedObject As Object, ByVal isReadOnly As Boolean)
  If selectedObject IsNot Nothing Then
    TypeDescriptor.AddAttributes(selectedObject, New Attribute[] { New ReadOnlyAttribute(isReadOnly) });
  End If
End Sub

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