簡體   English   中英

無法在PropertyGrid中顯示具有接口屬性的類

[英]Can't show class with interface properties in PropertyGrid

目前,我正在嘗試通過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僅用於使用確切類型的屬性。

顯示MyContainer的PropertyGrid http://image-upload.de/image/O2CC5e/9558e4e179.png

是否存在任何方法可以讓PropertyGrid在接口屬性后面顯示類的ToString()結果?

最后,我在大多數情況下解決了這個問題:

發生此問題,是因為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的屬性)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM