[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

若有谬误,烦请告知,新手发帖请多包涵

2010~2017 C# 第四季