【问题标题】:PropertyDescriptor and AttributesPropertyDescriptor 和属性
【发布时间】:2013-07-29 09:02:50
【问题描述】:

我继承了PropertyDescriptor 类来提供某种“动态”属性。我正在向 PropertyDescriptor 添加一些属性。这完美地工作。

PropertyGrid 中显示对象时,ReadOnlyAttribute 有效,但EditorAttribute 无效!

internal class ParameterDescriptor: PropertyDescriptor {
    //...
    public ParameterDescriptor(/* ... */) {
        List<Attribute> a = new List<Attribute>();
        string editor = "System.ComponentModel.Design.MultilineStringEditor,System.Design";
        //...
        a.Add(new ReadOnlyAttribute(true));                         // works
        a.Add(new DescriptionAttribute("text"));                    // works
        a.Add(new EditorAttribute(editor, typeof(UITypeEditor)));   // doesn't work!
        //...    
        this.AttributeArray = a.ToArray();
    }
}

显示的对象使用继承的TypeConverter

public class ParameterBoxTypeConverter: TypeConverter {
    public override bool GetPropertiesSupported(ITypeDescriptorContext context) {
        return true;
    }

    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) {
        List<PropertyDescriptor> desc = new List<PropertyDescriptor>();
        //...
        ParameterDescriptor d = new ParameterDescriptor(/* ... */);
        desc.Add(d);
        //....
        return new PropertyDescriptorCollection(desc.ToArray());
    }

我被卡住了,因为 PropertyGrid 根本没有显示任何东西(我希望属性值处有一个“...”)。而且好像没办法调试!

那么我怎样才能找到这里的问题呢?
有没有办法调试到 PropertyGrid 等?

【问题讨论】:

  • 你没有用a显示你然后做什么...你把它传递给基础ctor吗?还是...?
  • @MarcGravell:请看我的编辑。

标签: c# properties propertygrid propertydescriptor


【解决方案1】:

通过一些快速测试,名称需要完全限定:

const string name = "System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
attribs.Add(new EditorAttribute(name, typeof(UITypeEditor)));

在内部,它使用Type.GetType,并且:

var type1 = Type.GetType("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
// ^^^ not null
var type2 = Type.GetType("System.ComponentModel.Design.MultilineStringEditor, System.Design");
// ^^^ null

当然,你可以使用:

attribs.Add(new EditorAttribute(typeof(MultilineStringEditor), typeof(UITypeEditor)));

或者,您可以override GetEditor 做任何您想做的事情。

【讨论】:

  • 好点。最后,由于某些原因,我不能使用重载new EditorAttribute(typeof(MultilineStringEditor), typeof(UITypeEditor))。你是怎么知道Internally, it uses Type.GetType???
  • @joe 您是否缺少对System.Design.dll 的引用?我已经检查过了,它从 2.0 开始就被声明为public,所以它应该可以正常工作。你得到什么信息?关于后者:我在反射器中打开它。我可以也使用公共调试符号下载,但是反射器对我来说更方便。
  • @joe 获取信息,这里负责的方法是PropertyDescriptor.GetTypeFromName;不幸的是,虽然它是protected,但它不是virtual,所以你不能只是override
  • 我也检查了参考资料,一切都很好。在PropertyDescriptor 内调用GetTypeFromName("System.ComponentModel.Design.MultilineStringEditor") 表单也会返回null。
  • 原来Type.GetTypePropertyDescriptor.GetTypeFromName 都需要完全限定名称。我假设 name 和 dll 会出现在这里,但事实并非如此。所以我必须找出如何实现这一点。到目前为止,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 2013-09-05
相关资源
最近更新 更多