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