【问题标题】:Can't show class with interface properties in PropertyGrid无法在 PropertyGrid 中显示具有接口属性的类
【发布时间】:2011-12-16 10:16:01
【问题描述】:

目前我正在尝试通过 PropertyGrid 配置我的一些类。如果类将属性作为接口提供,现在我在显示值(网格内的右侧)方面存在一些问题。我想,由于网格使用反射,它会采用真实类型并使用它在网格中显示值的正常方式。对于演示,只需使用下面的类层次结构并使用 PropertyGrid 创建一个简单的表单,然后通过调用将对象放入其中

propertyGrid1.SelectedObject = new MyContainerClass();

以下是课程:

public class MyContainerClass
{
    // Simple properties that should be shown in the PropertyGrid
    public MyInterface MyInterface { get; set; }
    public MyClass MyClass { get; set; }
    public object AsObject { get; set; }

    public MyContainerClass()
    {
        // Create one instance of MyClass
        var myClass = new MyClass();

        // Put the instance into both properties
        // (cause MyClass implements MyInterface)
        MyClass = myClass;
        MyInterface = myClass;

        // and show it if it is declared as "object"
        AsObject = myClass;
    }
}

// Some kind of interface i'd like to show in the PropertyGrid.
public interface MyInterface
{
    string Name { get; set; }
}

// A class that also implements the interface
// and uses some kind of TypeConverter
[TypeConverter(typeof(ExpandableObjectConverter))]
public class MyClass : MyInterface
{
    // Create an instance and put something meaningful into the property.
    public MyClass()
    {
        Name = "MyName";
    }

    public string Name { get; set; }

    // Override ToString() to get something shown
    // as value in the PropertyGrid.
    public override string ToString()
    {
        return "Overridden ToString(): " + Name;
    }
}

如您所见,容器在所有三个属性中都使用了相同的对象,但在网格中,您会在类属性和对象属性上看到 ToString() 文本,但在接口属性上什么也没有。此外,TypeConverter 仅用于使用确切类型的属性。

PropertyGrid showing MyContainer http://image-upload.de/image/O2CC5e/9558e4e179.png

有没有办法让 PropertyGrid 显示接口属性后面的类的 ToString() 结果?

【问题讨论】:

    标签: c# winforms .net-4.0 propertygrid


    【解决方案1】:

    最后我在大多数情况下解决了这个问题:

    问题出现了,导致PropertyDescriptor 在其Converter 属性中返回通常正确的转换器或至少基类TypeConverter,它至少会调用ToString() 进行可视化。如果属性被定义为接口,属性网格将获得ReferenceConverter,但通过查看备注部分

    ReferenceConverter 通常在现场组件或设计环境的上下文中使用。如果没有组件站点或可用的 ITypeDescriptorContext,这个转换器就没什么用了。

    我们似乎真的有点用它。幸运的是我已经在使用我自己的PropertyDescriptor,所以我所要做的就是覆盖我的描述符的 Converter 属性并更改为以下内容:

    public override TypeConverter Converter
    {
        get
        {
            var converter = base.Converter;
    
            // If the property of the class is a interface, the default implementation
            // of PropertyDescriptor will return a ReferenceConverter, but that doesn't
            // work as expected (normally the right site will stay empty).
            // Instead we'll return a TypeConverter, that works on the concrete type
            // and returns at least the ToString() result of the given type.
            if (_OriginalPropertyDescriptor.PropertyType.IsInterface)
            {
                if (converter.GetType() == typeof(ReferenceConverter))
                {
                    converter = _InterfaceConverter;
                }
            }
    
            return converter;
        }
    }
    

    需要对ReferenceConverter 进行显式检查,因为用户可能通过属性上的属性定义了自己的TypeEditor,基本实现会自动遵守该属性。如果有人通过属性明确地说他喜欢 ReferenceConverter,只会导致问题,但我认为不必处理这种情况(但可以通过检查 PropertyDescriptor 的属性)。

    【讨论】:

      猜你喜欢
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多