6
我正在使用PropertyGrid控件编辑我的应用程序中的某些对象。我正在使用自定义的TypeConverters和TypeEditor以获得更好的用户界面。属性网格项目和DoubleClick
我有自定义TypeConverter布尔属性的问题。如果我有这个类:
public class MyClass {
public string Name { get; set; }
[System.ComponentModel.TypeConverter(typeof(BoolTypeConverter))]
public bool Flag { get; set; }
}
,我创建实例,并将其设置为SelectedObject在PropertyGrid中 - 一切都很好,直到用户属性网格项目形式“旗”财产上DoubleClicked。 DoubleClick会在提出了这个消息后:alt text http://tcks.wz.cz/property_grid_error.PNG
的类型转换器类如下:
public class BoolTypeConverter : System.ComponentModel.TypeConverter {
public const string TEXT_TRUE = "On";
public const string TEXT_FALSE = "Off";
public const string TEXT_NONE = "<none>";
public override object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) {
object ret = base.CreateInstance(context, propertyValues);
return ret;
}
public override bool GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context) {
bool ret = base.GetCreateInstanceSupported(context);
return ret;
}
public override bool IsValid(System.ComponentModel.ITypeDescriptorContext context, object value) {
bool ret;
if (value is string) {
string tmpValue = value.ToString().Trim();
if (string.Compare(tmpValue, TEXT_NONE, StringComparison.InvariantCultureIgnoreCase) == 0) {
ret = true;
}
else if (string.Compare(tmpValue, TEXT_TRUE, StringComparison.InvariantCultureIgnoreCase) == 0) {
ret = true;
}
else if (string.Compare(tmpValue, TEXT_FALSE, StringComparison.InvariantCultureIgnoreCase) == 0) {
ret = true;
}
else {
bool blValue;
ret = bool.TryParse(tmpValue, out blValue);
}
}
else {
ret = base.IsValid(context, value);
}
return ret;
}
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) {
bool ret = false;
if (sourceType == typeof(string)) {
ret = true;
}
else {
ret = base.CanConvertFrom(context, sourceType);
}
return ret;
}
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
object ret = null;
bool converted = false;
if (value is string) {
string tmpValue = value.ToString().Trim();
if (string.Compare(tmpValue, TEXT_NONE, StringComparison.InvariantCultureIgnoreCase) == 0
|| string.IsNullOrEmpty(tmpValue)) {
ret = null;
converted = true;
}
else if (string.Compare(tmpValue, TEXT_TRUE, StringComparison.InvariantCultureIgnoreCase) == 0) {
ret = true;
converted = true;
}
else if (string.Compare(tmpValue, TEXT_FALSE, StringComparison.InvariantCultureIgnoreCase) == 0) {
ret = false;
converted = true;
}
else {
bool blValue;
if (converted = bool.TryParse(tmpValue, out blValue)) {
ret = blValue;
}
}
}
if (false == converted) {
ret = base.ConvertFrom(context, culture, value);
}
return ret;
}
public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType) {
bool ret = false;
if (destinationType == typeof(bool)) {
ret = true;
}
else {
ret = base.CanConvertTo(context, destinationType);
}
return ret;
}
public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
object ret = null;
bool converted = false;
if (destinationType == typeof(string)) {
if (null == value) {
ret = TEXT_NONE;
converted = true;
}
else if (value is bool? || value is bool) {
if ((bool)value) { ret = TEXT_TRUE; }
else { ret = TEXT_FALSE; }
converted = true;
}
else if (value is string) {
ret = value;
converted = true;
}
}
if (false == converted) {
ret = base.ConvertTo(context, culture, value, destinationType);
}
return ret;
}
public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) {
StandardValuesCollection ret;
Type tpProperty = context.PropertyDescriptor.PropertyType;
if (tpProperty == typeof(bool)) {
ret = new StandardValuesCollection(new string[]{
TEXT_TRUE, TEXT_FALSE
});
}
else if (tpProperty == typeof(bool?)) {
ret = new StandardValuesCollection(new string[]{
TEXT_TRUE, TEXT_FALSE, TEXT_NONE
});
}
else {
ret = new StandardValuesCollection(new string[0]);
}
return ret;
}
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) {
bool ret;
Type tpProperty = context.PropertyDescriptor.PropertyType;
if (tpProperty == typeof(bool) || tpProperty == typeof(bool?)) {
ret = true;
}
else {
ret = false;
}
return ret;
}
}
这种行为对于用户来说非常混乱。我怎样才能防止它?
谢谢
太好了,您是对的。谢谢! – TcKs 2010-03-02 13:31:19
@Nicolas Cadilhac,谢谢!我花了多少小时来寻找这个答案! – Ben 2012-03-29 19:39:18
约8,在我的情况>。>。我继承了一个相当复杂的泛型TypeConverter,用于转换泛型枚举,而这个泛型枚举出现了这个问题,而且我几乎不知道从哪里开始,因为从PropertyGrid转换的处理大部分是内部的.net魔术。终于找到了这篇文章,这正是我几个小时前发现的。谢谢! (具体来说,它是创建[底层对象 - >字符串]的地图,然后GetStandardValues返回的是地图中的值而不是关键字。Yay。) – neminem 2012-04-17 16:15:52