Условный атрибут "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);
}