續上篇 自訂控制項的顯示視窗屬性 /User Control of Properties(二),為節省篇幅,VB語法就不列在上面了,需要的人再去下載範例。
顯示複雜屬性
我們可以利用.NET 本身所提供的類別拿來當傳遞
字型
實體化一個預設字型。
private Font _CustomFont = new Font("新細明體", 12, FontStyle.Regular);
[Category("自訂屬性"), Description("字型大小")]
public Font CustomFont
{
get { return _CustomFont; }
set { _CustomFont = value; }
}
顏色
private Color _CustombarColor = SystemColors.Control;
[Category("自訂屬性"), Description("控制項顏色")]
public Color CustombarColor
{
get { return _CustombarColor; }
set { _CustombarColor = value; }
}
尺寸
private Size _CustomSize = new Size(100, 100);
[Category("自訂屬性"), Description("視窗大小")]
public Size CustomSize
{
get { return _CustomSize; }
set { _CustomSize = value; }
}
圖形
[Category("自訂屬性"), Description("視窗大小")]
public Image CustomImage{get;set;}
看了以上幾個例子後,我們就可以知道屬性也可以把類別丟來丟去的。
自訂動態下拉清單
enum 可以達到下拉清單的功能,但萬一我們需要的清單是動態的,就沒辦法使用enum 了,這時我們可以這樣做:
1.建立繼承 StringConverter 類別,並複寫
1-1 覆寫 GetStandardValuesSupported 方法並傳回 true,表示能從清單挑選值。
1-2 覆寫 GetStandardValues 方法,並傳回填入您的標準值的 StandardValuesCollection。表示建立清單選擇。
1-3 覆寫 GetStandardValuesExclusive 方法並傳回 false。讓使用者能輸入下拉式清單以外的值。
public class NameConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[] { "余小章", "張大呆", "吳小明" });
}
//(選擇性) 讓使用者能輸入下拉式清單以外的值
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
}
2.建立屬性
public partial class CSUserControl1 : UserControl
{
public CSUserControl1()
{
InitializeComponent();
}
private string _DefaultFileName="余小章";
[TypeConverter(typeof(NameConverter)), CategoryAttribute("自訂屬性"), Description("自訂清單")]
public string DefaultFileName
{
get { return _DefaultFileName; }
set { _DefaultFileName = value; }
}
}
回傳自訂類別
當自己開發一個類別後要怎麼在屬性視窗裡顯示?
參考http://dotnetframework.blogspot.com/2007/10/blog-post.html
1.首先先建立一個類別,並定義 RefreshProperties 屬性。
public class CustomClass
{
private string _CustomName = "余小章";
[Category("自訂屬性"), Description("自訂名稱"), RefreshProperties(RefreshProperties.All)]
public string CustomName
{
get { return _CustomName; }
set { _CustomName = value; }
}
private int _CustomAge = 19;
[Category("自訂屬性"), Description("自訂年齡"), RefreshProperties(RefreshProperties.All)]
public int CustomAge
{
get { return _CustomAge; }
set { _CustomAge = value; }
}
}
此處的RefreshProperties 屬性主要是用來自動更新其它屬性
2.建立一繼承ExpandableObjectConverter個類別,並覆寫
CanConvertTo:傳回型別轉換子是否能將物件轉換成指定的型別。
ConvertTo:用來存放資訊,將指定的值物件轉換為指定的型別,如下圖:
CanConvertFrom: (選擇性) 可以指定型別轉換器可以從字串轉換,以便在文字方塊中編輯物件的字串,如下圖:
ConvertFrom:從指定的值轉換成此轉換子的預期轉換型別。
public class CustomClassConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType)
{
if (destinationType == typeof(CustomClass))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, System.Type destinationType)
{
if (destinationType == typeof(System.String) && value is CustomClass)
{
CustomClass so = (CustomClass)value;
return "名字:" + so.CustomName + "," +
"年齡為:" + so.CustomAge;
}
return base.ConvertTo(context, culture, value, destinationType);
}
//(選擇性) 您可以指定型別轉換器可以從字串轉換,以便在文字方塊中編輯物件的字串
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
try
{
string str = (string)value;
int colon = str.IndexOf(':');
int comma = str.IndexOf(',');
if (colon != -1 && comma != -1)
{
string name = str.Substring(colon + 1, (comma - colon - 1));
colon = str.IndexOf(':', comma + 1);
string age = str.Substring(colon + 1);
CustomClass so = new CustomClass();
so.CustomAge = Int16.Parse(age);
so.CustomName = name;
return so;
}
}
catch
{
throw new ArgumentException("無法將 '" + (string)value + "' 轉換為 CustomClass 型別");
}
}
return base.ConvertFrom(context, culture, value);
}
}
3.套用CustomClassConverter 類別,加入TypeConverterAttribute屬性
[TypeConverterAttribute(typeof(CustomClassConverter))]
public class CustomClass
{
}
4.在自訂控制項中引用自訂類別
private CustomClass _CustomClass = new CustomClass();
[Category("自訂屬性"), Description("自訂類別")]
public CustomClass CustomClass
{
get { return _CustomClass; }
set { _CustomClass = value; }
}
範例下載