简体   繁体   English

PropertyGrid - 它可以自定义吗?

[英]PropertyGrid - is it customizable?

I have a project in that we have to represent some graphic objects on a usercontrol in WYSIWYG. 我有一个项目,我们必须在WYSIWYG中的用户控件上表示一些图形对象。 Also is required to edit each objects properties(Color, Location, etc). 还需要编辑每个对象属性(颜色,位置等)。

alt text http://lh6.ggpht.com/_1TPOP7DzY1E/TBHz8PW8MQI/AAAAAAAADPE/kzAbKKsEkmU/s144/Untitled.gif 替代文字http://lh6.ggpht.com/_1TPOP7DzY1E/TBHz8PW8MQI/AAAAAAAADPE/kzAbKKsEkmU/s144/Untitled.gif

I hesitate between using PropertyGrid ('direct' properties edit) and custom forms on DoubleClick ('indirect' edit). 我在使用PropertyGrid('直接'属性编辑)和DoubleClick上的自定义表单('间接'编辑)之间犹豫不决。

The PropertyGrid is very well but should correspond a some criteria: PropertyGrid非常好,但应该符合一些标准:

  • Only selected properties are Displayed (by eg if I have TextRectangle want display only Text and Location); 只有选定的属性显示(通过例如,如果我有TextRectangle想显示文本和位置);
  • Property names should be customizable and internationalizable (by eg TextRectangle Text property should be named "Company Name" or "Название предприятия"). 属性名称应该是可自定义和可国际化的(例如,TextRectangle Text属性应命名为“Company Name”或“Названиепредприятия”)。

Now about is it possible I think the answer could be Yes, but is it reasonable to use it if we have not a lot of time. 现在关于我是否有可能认为答案可能是肯定的,但如果我们没有太多时间,使用它是否合理。 What could be quicker implemented, custom forms or Property panel? 什么可以更快实现,自定义表单或属性面板?

EDIT: 编辑:
The most examples I saw on internet was with totally custom objects witch properties can be easy managed. 我在互联网上看到的大多数例子都是完全自定义的对象,可以轻松管理属性。 The problem I have is that I would display also ready .NET Framework objects that I can't control like TextBoxes, Label, RectangleShape or OvalShape(VB.Powerpacks) 我遇到的问题是我还会显示我无法控制的.NET Framework对象,如TextBoxes,Label,RectangleShape或OvalShape(VB.Powerpacks)

Is there a possibility to hide all properties and only indicate a few ones that should be present? 是否有可能隐藏所有属性并仅指出应该存在的几个属性?

PropertyGrid is customizable using attributes on the displayed classes. PropertyGrid可以使用显示的类上的属性进行自定义。

Using a TypeConverter you can control the look & feel of properties and/or objects in the PropertyGrid. 使用TypeConverter,您可以控制PropertyGrid中属性和/或对象的外观。 You can use it to add "virtual" properties, or leave properties out. 您可以使用它来添加“虚拟”属性,或者保留属性。 Also the name of the property can be changed / localized. 此外,可以更改/本地化属性的名称。 But a Typeconverter is somewhat harder to implement as the other options. 但是,作为其他选择,Typeconverter实施起来有点困难。

With the UITypeEditor you can control how a property should be edited (inline, show your own dialog, colorpicker, ...) 使用UITypeEditor,您可以控制如何编辑属性(内联,显示您自己的对话框,颜色选择器......)

You can attach a DisplayName to a property, to change the name. 您可以将DisplayName附加到属性,以更改名称。 If you override the class, you can translate the propertynames. 如果您覆盖该类,则可以翻译属性名称。 This question has an example how to do this. 这个问题有一个例子如何做到这一点。

And (like Rune Grimstad answered) you leave out properties by putting a [Browsable(false)] attribute on them. 并且(像Rune Grimstad回答的那样)你通过在它们上面加上[Browsable(false)]属性来省略属性。

Another nice one is the DefaultValue , if the value of an attribute matches the value provided by the DefaultValue, the value uses the normal font. 另一个不错的是DefaultValue ,如果属性的值与DefaultValue提供的值匹配,则该值使用普通字体。 If it differs it uses a Bold font. 如果它不同,则使用粗体字体。

Your problem is that you do not want to inherit from TextBox or other classes all the time. 您的问题是您不希望始终从TextBox或其他类继承。 You can encapsulate the Textbox in a wrapper, that only exposes (via a TypeConverter) the properties you need. 您可以将文本框封装在一个包装器中,该包装器仅公开(通过TypeConverter)您需要的属性。 I've hacked something that does this: 我已经攻击了这样做的东西:

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")
        });
    }
}

To make a textbox the selected object, you use: 要使文本框成为所选对象,请使用:

this.propertyGrid1.SelectedObject = new TextboxWrapper(this.textBox1);

The place to further work this out is in the pd (ugly name, I know) class, to include the data type, and a localized labels. 进一步解决这个问题的地方是pd(丑陋的名字,我知道)类,包括数据类型和本地化标签。

The property grid will check the selected objects properties for certain attributes: 属性网格将检查某些属性的选定对象属性:

This means that you can hide some properties and partially control how the properties are displayed, but you can't add custom or translated property names as far as I know. 这意味着您可以隐藏某些属性并部分控制属性的显示方式,但据我所知,您无法添加自定义或已翻译的属性名称。

Check the docs on MSDN for more information . 有关详细信息,请查看MSDN上的文档

Edit: You should check out this article on Codeproject about a globalized property grid. 编辑:您应该在Codeproject上查看有关全球化属性网格的这篇文章 It seems to do what you are after. 它似乎做你想要的。

You might look at this article on CodeProject. 您可以在CodeProject上查看这篇文章 It uses a generic PropertyBag object to contain whatever properties you want to expose from your object(s) and gives the PropertyBag to the PropertyGrid to display. 它使用通用的PropertyBag对象来包含要从对象公开的任何属性,并将PropertyBag提供给PropertyGrid以显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM