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


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

5 ответов


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

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

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

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


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

/// <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's Properties
    PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(this.GetType())[strPropertyName];

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

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

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


я наткнулся на это в поисках способа объявить определенные члены видимыми или скрытыми в 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, и это было поспешно преобразовано в c#. Если что-то пойдет не так, дай мне знать.


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

    /// <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's Properties
        PropertyDescriptor theDescriptor = TypeDescriptor.GetProperties(typeof(T))[strPropertyName];

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

        // Set the Descriptor's "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);
    }