作者:
綸巾客 來源:
博客園 發布時間: 2009-02-27 15:23 閱讀: 2344 次 推薦: 0
原文鏈接 [收藏]
前面的幾篇文章中,我們給控件添加一個復雜的類型Scope,并且給它的類型提供的一個類型轉換器,現在我們可以在屬性瀏覽器中編輯它的值,并且它的值也被串行化的源代碼里了。但是你有沒有發現,在屬性瀏覽器里編輯這個屬性的值還是不太方便。因為屬性只是“10,200”這種形式的,所以,你必須按照這種格式來修改,一旦格式錯誤就會引發異常,比如輸入一個“10200”。我們期望這個屬性的每一子屬性都能夠被獨立的編輯就好了,這并非不能實現,而且實現還很簡單。
為了在屬性瀏覽器里能夠獨立的編輯子屬性,我們還要重寫兩個方法:GetPropertiesSupported()和GetProperties();下面是ScopeConverter的完整代碼:
public class ScopeConverter : TypeConverter

{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)

{
if (sourceType == typeof(String)) return true;

return base.CanConvertFrom(context, sourceType);
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)

{
if (destinationType == typeof(String)) return true;

if (destinationType == typeof(InstanceDescriptor)) return true;

return base.CanConvertTo(context, destinationType);
}

public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.
CultureInfo culture, object value, Type destinationType)

{
String result = "";
if (destinationType == typeof(String))

{
Scope scope = (Scope)value;
result = scope.Min.ToString()+"," + scope.Max.ToString();
return result;

}

if (destinationType == typeof(InstanceDescriptor))

{

ConstructorInfo ci = typeof(Scope).GetConstructor(new Type[]
{typeof(Int32),
typeof(Int32) });
Scope scope = (Scope)value;

return new InstanceDescriptor(ci, new object[]
{ scope.Min,scope.Max });
}
return base.ConvertTo(context, culture, value, destinationType);
}

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.
CultureInfo culture, object value)

{
if (value is string)

{
String[] v = ((String)value).Split(',');
if (v.GetLength(0) != 2)

{
throw new ArgumentException("Invalid parameter format");
}

Scope csf = new Scope();
csf.Min = Convert.ToInt32(v[0]);
csf.Max = Convert.ToInt32(v[1]);
return csf;
}
return base.ConvertFrom(context, culture, value);
}

public override bool GetPropertiesSupported(ITypeDescriptorContext context)

{
return true;
}

public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,
object value, Attribute[] attributes)

{
return TypeDescriptor.GetProperties(typeof(Scope), attributes);
}
}

在GetProperties方法里,我用TypeDescriptor獲得了Scope類的所有的屬性描述器并返回。如果你對TypeDescriptor還不熟悉的話,可以參考MSDN。
重寫這兩個方法并編譯以后,在測試工程里查看控件的屬性,你可以看到Scope是如下的形式:

文章列表