[C#.NET][VB.NET][Winform][User Control] 自訂控制項的顯示視窗屬性 /User Control of Properties(二)

[C#.NET][VB.NET][Winform][User Control] 自訂控制項的顯示視窗屬性 /User Control of Properties(二)

續上篇 自訂控制項的顯示視窗屬性 /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; }
}

2010-6-15 下午 04-29-09

顏色

private Color _CustombarColor = SystemColors.Control;
[Category("自訂屬性"), Description("控制項顏色")]
public Color CustombarColor
{
    get { return _CustombarColor; }
    set { _CustombarColor = value; }
}

2010-6-15 下午 04-38-50

尺寸

private Size _CustomSize = new Size(100, 100);
[Category("自訂屬性"), Description("視窗大小")]
public Size CustomSize
{
    get { return _CustomSize; }
    set { _CustomSize = value; }
}

2010-6-15 下午 04-38-14

圖形

[Category("自訂屬性"), Description("視窗大小")]
public Image CustomImage{get;set;}
2010-6-15 下午 04-40-41 

看了以上幾個例子後,我們就可以知道屬性也可以把類別丟來丟去的。

自訂動態下拉清單

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; }
    } 
}
2010-6-15 下午 05-21-33 

回傳自訂類別

當自己開發一個類別後要怎麼在屬性視窗裡顯示?

參考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 屬性主要是用來自動更新其它屬性

 

2010-6-15 下午 06-44-40

2.建立一繼承ExpandableObjectConverter個類別,並覆寫

CanConvertTo:傳回型別轉換子是否能將物件轉換成指定的型別。

ConvertTo:用來存放資訊,將指定的值物件轉換為指定的型別,如下圖:

2010-6-15 下午 07-00-56

CanConvertFrom: (選擇性) 可以指定型別轉換器可以從字串轉換,以便在文字方塊中編輯物件的字串,如下圖:

2010-6-15 下午 06-49-21

ConvertFrom:從指定的值轉換成此轉換子的預期轉換型別。

2010-6-15 下午 06-53-33

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; }
}

 

範例下載

UserControls-1.zip

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo