PropertyGrid - это настраиваемый? - PullRequest
3 голосов
/ 11 июня 2010

У меня есть проект, в котором мы должны представлять некоторые графические объекты в пользовательском контроле в WYSIWYG.Также требуется для редактирования каждого объекта свойства (цвет, местоположение и т. Д.).

альтернативный текст http://lh6.ggpht.com/_1TPOP7DzY1E/TBHz8PW8MQI/AAAAAAAADPE/kzAbKKsEkmU/s144/Untitled.gif

Я колеблюсь между использованием PropertyGrid (прямое редактирование свойств) и настраиваемых форм в DoubleClick (косвенное редактирование).

PropertyGrid очень хорошо, но должен соответствовать некоторым критериям:

  • Отображаются только выбранные свойства (например, если у меня есть TextRectangle, хочу отображать только Текст иМесто нахождения);
  • Имена свойств должны быть настраиваемыми и интернационализируемыми (например, TextRectangle свойство Text должно называться «Название компании» или «Название предприятия»).

Теперь о том, возможно ли это, я думаю,Ответ может быть да, но разумно ли его использовать, если у нас не так много времени.Что может быть быстрее реализовано, пользовательские формы или панель свойств?

РЕДАКТИРОВАТЬ:
Большинство примеров, которые я видел в Интернете, были с полностью настраиваемыми объектами свойствами ведьмы можно легко управлять.У меня проблема в том, что я буду отображать также готовые объекты .NET Framework, которые я не могу контролировать, такие как TextBoxes, Label, RectangleShape или OvalShape (VB.Powerpacks)

Есть ли возможность скрыть все свойства и толькоуказать несколько из них, которые должны присутствовать?

Ответы [ 3 ]

2 голосов
/ 11 июня 2010

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 (я знаю, уродливое имя), чтобы включить тип данных и локализованные метки.

1 голос
/ 17 июня 2010

Вы можете посмотреть эту статью на CodeProject.Он использует универсальный объект PropertyBag для хранения любых свойств, которые вы хотите предоставить из ваших объектов, и передает PropertyBag в PropertyGrid для отображения.

1 голос
/ 11 июня 2010

Сетка свойств будет проверять свойства выбранных объектов на наличие определенных атрибутов:

  • BrowsableAttribute может использоваться для скрытия свойства в сетке свойств
  • Атрибут Description содержит описательный текст, который может отображаться в сетке свойств

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

Проверьте документы на MSDN для получения дополнительной информации .

Edit: Вы должны проверить эту статью о Codeproject о глобализированной сетке свойств. Кажется, он делает то, что тебе нужно.

...