Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';在PropertyGrid中不显示具有接口属性的类_C#_Winforms_.net 4.0_Propertygrid - Fatal编程技术网

C# Can';在PropertyGrid中不显示具有接口属性的类

C# Can';在PropertyGrid中不显示具有接口属性的类,c#,winforms,.net-4.0,propertygrid,C#,Winforms,.net 4.0,Propertygrid,目前,我正试图通过PropertyGrid配置一些类。现在,如果类将属性作为接口提供,那么在显示值(网格中的右侧)时会遇到一些问题。我想,因为网格使用反射,它将采用真实的类型,并使用它的正常方式来显示网格中的值。对于演示,只需使用下面的类层次结构,创建一个带有PropertyGrid的简单表单,并通过调用 propertyGrid1.SelectedObject = new MyContainerClass(); 以下是课程: public class MyContainerClass {

目前,我正试图通过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;
    }
}
正如您所看到的,容器在所有三个属性中都使用相同的对象,但在网格中,您将在class属性和object属性上看到
ToString()
文本,但在interface属性上看不到任何内容。此外,TypeConverter仅用于使用确切类型的属性


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

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

出现此问题时,会导致
PropertyDescriptor
在其
Converter
属性中返回正确的转换器,或者至少返回基类
TypeConverter
,该基类至少会调用
ToString()
进行可视化。对于定义为接口的属性,属性网格将获得一个,但通过查看备注部分

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的属性来处理)。

最后,我解决了大多数情况下的此问题:

出现此问题时,会导致
PropertyDescriptor
在其
Converter
属性中返回正确的转换器,或者至少返回基类
TypeConverter
,该基类至少会调用
ToString()
进行可视化。对于定义为接口的属性,属性网格将获得一个,但通过查看备注部分

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的属性)