将使用类型转换器的用户控件
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);
}
}
答案 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
开始工作的。