PropertyGrid настраивается с использованием атрибутов отображаемых классов.
Используя TypeConverter , вы можете управлять внешним видом свойств и / или объектов в PropertyGrid. Вы можете использовать его для добавления «виртуальных» свойств или пропустить свойства. Также название недвижимости может быть изменено / локализовано. Но преобразователь Typec несколько сложнее реализовать, чем другие варианты.
С помощью UITypeEditor вы можете контролировать, как должно редактироваться свойство (inline, показывать свой собственный диалог, палитру цветов, ...)
Вы можете прикрепить DisplayName к свойству, чтобы изменить имя. Если вы переопределите класс, вы можете перевести имена свойств. В этом вопросе есть пример, как это сделать.
И (как ответил Руне Гримстад) вы пропускаете свойства, помещая в них атрибут [Browsable (false)].
Другим хорошим вариантом является DefaultValue , если значение атрибута совпадает со значением, предоставленным DefaultValue, значение использует обычный шрифт. Если он отличается, он использует шрифт Bold .
Ваша проблема в том, что вы не хотите все время наследовать от TextBox или других классов. Вы можете инкапсулировать Textbox в оболочку, которая только предоставляет (через TypeConverter) нужные вам свойства. Я взломал что-то, что делает это:
class BaseWrapper<T> {
public BaseWrapper(T tb) {
this.Wrapped = tb;
}
[Browsable(false)]
public T Wrapped { get; set; }
public object GetMember(string name) {
var prop = this.Wrapped.GetType().GetProperty(name);
return prop.GetValue(this.Wrapped, null);
}
public void SetMember(string name, object value) {
var prop = this.Wrapped.GetType().GetProperty(name);
prop.SetValue(this.Wrapped, value, null);
}
}
class BaseConverter<T> : TypeConverter {
protected class pd : SimplePropertyDescriptor {
public pd(string displayName, string name) : base(typeof(BaseWrapper<T>), displayName, typeof(string)) {
this.PropName = name;
}
public string PropName { get; set; }
public override object GetValue(object component) {
var wrapper = (BaseWrapper<T>)component;
return wrapper.GetMember(this.PropName);
}
public override void SetValue(object component, object value) {
var wrapper = (BaseWrapper<T>)component;
wrapper.SetMember(this.PropName, value);
}
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context) {
return true;
}
}
[TypeConverter(typeof(TextBoxConverter))]
class TextboxWrapper : BaseWrapper<TextBox> {
public TextboxWrapper(TextBox t) : base(t) { }
}
class TextBoxConverter : BaseConverter<TextBox> {
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) {
return new PropertyDescriptorCollection(new PropertyDescriptor[] {
new pd("Название предприятия", "Text")
});
}
}
Чтобы сделать текстовое поле выделенным объектом, вы используете:
this.propertyGrid1.SelectedObject = new TextboxWrapper(this.textBox1);
Место для дальнейшей работы - в классе pd (я знаю, уродливое имя), чтобы включить тип данных и локализованные метки.