Условный атрибут "Browsable"


Есть ли способ сделать атрибут "Browsable" условным, поэтому свойство, которое его применяет, иногда появляется на странице свойств, а иногда нет?
спасибо:)

Ответы

Ответ 1

Нет простого способа.

Вы можете это решить, реализовав ICustomTypeDescriptor. Вот хорошая статья о реализации ICustomTypeDescriptor.

Или вы можете связать свой собственный ControlDesigner с вашим классом и переопределить PreFilterProperties для добавления или удаления свойств, просматриваемых в сетке свойств.

Удаление определенных свойств из сетки свойств.

Ответ 2

Я не уверен, что это относится к вашей ситуации, но вы можете настроить "обозреваемое" украшение во время выполнения, вызывая функцию ниже.

/// <summary>
/// Set the Browsable property.
/// NOTE: Be sure to decorate the property with [Browsable(true)]
/// </summary>
/// <param name="PropertyName">Name of the variable</param>
/// <param name="bIsBrowsable">Browsable Value</param>
private void setBrowsableProperty(string strPropertyName, bool bIsBrowsable)
{
    // Get the Descriptor Properties
    PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(this.GetType())[strPropertyName];

    // Get the Descriptor "Browsable" Attribute
    BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)];
    FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance);

    // Set the Descriptor "Browsable" Attribute
    isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable);
}

Ответ 3

Вы можете сделать это, предоставив пользовательскую модель типа; на простейшем уровне вы можете предоставить пользовательский TypeDescriptor для вашего типа, полученный из ExpandableObjectConverter, и просто включить/исключить данное свойство по своему усмотрению, но это работает только с PropertyGrid - используется страница свойств. Более сложный подход заключается в использовании ICustomTypeDescriptor/TypeDescriptionProvider - это может работать внутри таких вещей, как DataGridView

Ответ 4

Я столкнулся с этим в поисках способа объявить определенные элементы видимыми или скрытыми в IntelliSense и иметь возможность изменить его один раз для всего, что нужно было скрывать во время компиляции. Я не могу сказать, было ли это то, что вы искали или нет, но я нашел ответ на свой вопрос... подумал, что это не помешает поделиться.

Я устанавливаю условный символ компиляции (находится на вкладке "Сборка" свойств проекта). IS_VIS (значение true, если вы хотите, чтобы некоторые участники отображались, false, если вы хотите их скрыть), а затем:

#if IS_VIS
    public const System.ComponentModel.EditorBrowsableState isVis =
        ComponentModel.EditorBrowsableState.Always;
#else
    public const System.ComponentModel.EditorBrowsableState isVis =
        ComponentModel.EditorBrowsableState.Never;
#endif

вы ссылаетесь на переменную isVis в атрибуте:

[EditorBrowsable(isVis)]
public string myMethod...

Я сделал это в VB, и это было поспешно преобразовано в С#. Если что-то не работает правильно, дайте мне знать.

Ответ 5

В качестве улучшения в @neoikon ответьте выше и, чтобы избежать исключения Ganesh, упомянутого в комментариях, вот версия, которая использует generics для получения типа:

    /// <summary>
    /// Set the Browsable property.
    /// NOTE: Be sure to decorate the property with [Browsable(true)]
    /// </summary>
    /// <param name="PropertyName">Name of the variable</param>
    /// <param name="bIsBrowsable">Browsable Value</param>
    private void SetBrowsableProperty<T>(string strPropertyName, bool bIsBrowsable)
    {
        // Get the Descriptor Properties
        PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(typeof(T))[strPropertyName];

        // Get the Descriptor "Browsable" Attribute
        BrowsableAttribute theDescriptorBrowsableAttribute = (BrowsableAttribute)theDescriptor.Attributes[typeof(BrowsableAttribute)];
        FieldInfo isBrowsable = theDescriptorBrowsableAttribute.GetType().GetField("Browsable", BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance);

        // Set the Descriptor "Browsable" Attribute
        isBrowsable.SetValue(theDescriptorBrowsableAttribute, bIsBrowsable);
    }

Затем вы также можете добавить версию, которая принимает экземпляр:

    /// <summary>
    /// Set the Browsable property.
    /// NOTE: Be sure to decorate the property with [Browsable(true)]
    /// </summary>
    /// <param name="obj">An instance of the object whose property should be modified.</param>
    /// <param name="PropertyName">Name of the variable</param>
    /// <param name="bIsBrowsable">Browsable Value</param>
    private void SetBrowsableProperty<T>(T obj, string strPropertyName, bool bIsBrowsable)
    {
        SetBrowsableProperty<T>(strPropertyName, bIsBrowsable);
    }

Использование:

    class Foo
    {
        [Browsable(false)]
        public string Bar { get; set; }
    }
    void Example()
    {
        SetBrowsableProperty<Foo>("Bar", true);
        Foo foo = new Foo();
        SetBrowsableProperty(foo, "Bar", false);
    }