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