为特定类型的下拉项实现类型转换器

时间:2018-11-11 23:08:49

标签: c# .net typeconverter

将使用类型转换器的用户控件

Public Class MYControl : Usercotrol 
{

private ListItem _Language;
[TypeConverter(typeof(LanguageEditor))]
public ListItem Language
    {
        get
        {
            return _Language;
        }
        set
        {
            _Language= value;
        }
    }
}

在下拉属性窗口中列出的类型

public class ListItem
{
    private string _Name;
    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }
    private string _Value;
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            _Value = value;
        }
    }
    public ListItem(string Name, string value)
    {
        _Value = value;
        _Name = Name;
    }

    public override string ToString()
    {
        return this._Name;
    }
}

我该如何实现类型转换器,这是我尝试没有成功的

public class LangEditor : TypeConverter
{
    private ArrayList values;

    public LangEditor()
    {
        // Initializes the standard values list with defaults.
        values = new ArrayList();
        foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

            values.Add(new ListItem(ci.DisplayName, ci.Name));
    } // New

    // Indicates this type converter provides a list of standard values.
    public new override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
    {
        return true;
    } // GetStandardValuesSupported

    // Returns a StandardValuesCollection of standard value objects.
    public new override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
    {
        // Passes the local value array.
        StandardValuesCollection svc = new StandardValuesCollection(values);
        return svc;
    } 

    public new override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
    {
        var propItem = context.Instance as ListItem;
        return propItem != null && TypeDescriptor.GetConverter(typeof(ListItem)).CanConvertFrom(context, sourceType) || base.CanConvertFrom(context, sourceType);
    } // CanConvertFrom

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var propItem = context.Instance as ListItem;

        if (propItem != null)
            return TypeDescriptor.GetConverter(typeof(ListItem)).ConvertFrom(context, culture, value);
        else
            return base.ConvertFrom(context, culture, value, ListItem);
    }
}

1 个答案:

答案 0 :(得分:1)

除了一些语法和编译器错误外,如注释中所述,主要问题是您的ConvertFrom方法希望返回ListItem。即使这是您在StandardValuesCollection中提供的内容,设计人员也不了解您的Type。

设计器需要一个字符串作为下拉列表,在这种情况下,将使用您的ToString()方法。但是您将取回该字符串以进行转换/重新水化。

如果您希望 Type 与它的所有使用相关联,则可能还想用它来装饰它。仅装饰TypeConverter属性意味着用法有转换器。这使调试变得很困难。

我还为转换器使用了惯用的名称。

UserControl

主要问题出在//Public Class MYControl : Usercotrol public class MYControl : UserControl { public ListItem Language {get; set;} } // Associate the TypeConverter with the Type, not property [TypeConverter(typeof(ListItemConverter))] public class ListItem { public string Name {get; set;} public string Value {get; set;} // serialization will need this public ListItem() { } public ListItem(string name, string value) { Value = value; Name = name; } public override string ToString() { return this.Name; } }

Can/ConvertFrom

设计者使用下拉列表和 var propItem = context.Instance as ListItem; if (propItem != null) ... 的名称(字符串),用户选择一个字符串,这就是您将返回的内容,而不是string

转换器还应该覆盖ListItem-用户不能伪造或键入新的语言,提供的语言是唯一合法的语言,不是吗?

GetStandardValuesExclusive代码中的其他更改包括:

  • 使用TypeConverter而不是过时的List
  • 从覆盖中删除ArrayList,以便进行编译
  • new仅需要是一个字符串集合,所以我对其进行了更改以从列表中获取名称。

StandardValuesCollection

public class ListItemConverter : TypeConverter { private List<ListItem> languages; public ListItemConverter() { // Initializes the standard values list with defaults. languages = new List<ListItem>(); foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) { languages.Add(new ListItem(ci.DisplayName, ci.Name)); } } // Indicates this type converter provides a list of standard values. public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) { return true; } public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) { // Passes the local array. StandardValuesCollection svc = new StandardValuesCollection(languages); return svc; } public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType) { if (sourceType == typeof(string)) { // where the debug code goes return true; } else return base.CanConvertFrom(context, sourceType); } // ADDED: the list is exclusive - no new entries allowed public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if(value is string) { ListItem item = (ListItem)languages. FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0)); return item; } else return base.ConvertFrom(context, culture, value); } } 中,您只需要查找返回的显示名称,在集合中找到相关的ListItem并将其返回。 ConvertFrom应该永远不会失败,并返回默认值(null),因为您是从排他性的 FirstOrDefault开始工作的。