C# Winform常见的Editor及其它经验

1、新建一个自定义Editor,继承自.NET自带的Editor,override某些方法,再附加到属性中:

public class MyCollectionEditor : CollectionEditor
{
    public MyCollectionEditor(Type type) : base(type)
    {
    }
    protected override void ShowHelp()
    {
        MessageBox.Show("别点了,点了也没用。");
    }
}
[Editor(typeof(MyCollectionEditor), typeof(UITypeEditor))]
public List<B> Bs2 { get; set; }

上图就在列表编辑框中重定义了点击“Help”时的操作。一般都是这么用的。

2、常见Editor

1)ArrayEditor,继承自CollectionEditor

2)BinaryEditor

3)CollectionEditor

4)DateTimeEditor

5)MultilineStringEditor

6)BitmapEditor,继承自ImageEditor

7)ColorEditor

8)ContentAlignmentEditor

9)CursorEditor

10)FontEditor

11)FontNameEditor

12)IconEditor

13)ImageEditor

14)MetafileEditor

15)UITypeEditor,所有这些的基类,他们能继承自它,我们怎么不行?

16)QueuePathEditor

17)DataControlReferenceCollectionEditor,继承自CollectionEditor

18)AppSettingsExpressionEditor,继承自ExpressionEditor

19)CollectionEditorBase,继承自CollectionEditor

20)ConnectionStringEditor

21)ConnectionStringsExpressionEditor,继承自ExpressionEditor

22)DataBindingCollectionEditor

23)ExpressionEditor

24)ExpressionCollectionEditor

25)ImageUrlEditor,继承自UrlEditor

26)MailFileEditor,继承自UrlEditor

27)MdbDataFileEditor,继承自UrlEditor

28)ResourceExpressionEditor,继承自ExpressionEditor

29)RouteUrlEditor,继承自ExpressionEditor

30)RouteValueExpressionEditor,继承自ExpressionEditor

31)ServiceReferenceCollectionEditor,继承自CollectionEditorBase

32)UpdatePanelTriggerCollectionEditor,继承自CollectionEditorBase

33)UrlEditor

34)UserControlFileEditor,继承自UrlEditor

35)AnchorEditor

36)BorderSidesEditor

37)DockEditor

38)FileNameEditor

39)FolderNameEditor

40)FormatStringEditor

41)ImageListImageEditor

42)ShortcutKeysEditor

43)BindingUIEditor

44)TypeBrowserEditor

还有部分Web命名空间下的没有记录,寻找方法,在对象浏览器中,搜索Editor,找出以Editor结尾,并继承自UITypeEditor的类即可。

3、可展开项的示例

[TypeConverter(typeof(ExpandableObjectConverter))]
public class B
{
    public int Name1 { get; set; }
    public int Name2 { get; set; }
    public override string ToString()
    {
        return Name1 + "-" + Name2;
    }
}
public class A
{
    public A()
    {
        if (Bs == null)
        {
            Bs = new B();
        }
    }
    public B Bs { get; set; }
}

 4、下拉框的示例

public class XXXConverter : StringConverter
{
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(StringArray);
    }
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }
    public static string[] StringArray = new[] { "AAA", "BBB" };
}
[TypeConverter(typeof(XXXConverter))]
public string Name2 { get; set; }

5、有效性验证示例

public class OneTo32Converter : Int32Converter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var result = (int)base.ConvertFrom(context, culture, value);
        if (result < 1 || result > 32)
        {
            throw new Exception("输入值要在1至32之间。");
        }
        return result;
    }
}
[TypeConverter(typeof(OneTo32Converter))]
public int Name1 { get; set; }

 6、数组自定义显示及去除展开对话框示例

public class XXXArrayConverter : ArrayConverter
{
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        return "sssss";
    }
}
[TypeConverter(typeof(XXXArrayConverter)), Editor(typeof(UITypeEditor), typeof(UITypeEditor))]
public B[] Bs { get; set; }

 7、Converter及Editor总结

如果附在uint类型的属性上,则:

Converter是用于该属性的类型uint与用于显示的类型string之间的转换;

ConvertFrom是string转换成uint;

ConvertTo是uint转换成string;

如果使用DateTimeEditor,则:

该Editor是用于uint与DateTime之间的转换;

而DateTimeEditor只会处理DateTime与DateTime之间的转换,所以要在EditValue方法中完成uint与DateTime的转换。

public class MyDateTimeEditor : DateTimeEditor
{
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var result = (DateTime) base.EditValue(context, provider, new DateTime(1970, 1, 1).AddSeconds((uint) value));
        return (uint) ((result - new DateTime(1970, 1, 1)).TotalSeconds);
    }
}
[TypeConverter(typeof(UInt32Converter)), Editor(typeof(MyDateTimeEditor), typeof(UITypeEditor))]
public uint C { get; set; }

Converter用于处理输入值时的行为,常用于有效性验证、格式转换等,而Editor用于处理下拉或打开新窗口时的行为。它们可以在同一个属性上共存。

8、自定义窗体示例

public class MyUITypeEditor : UITypeEditor
{
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var picker = new Form1((uint) value);
        if (picker.ShowDialog() == DialogResult.OK)
        {
            return picker.Seconds;
        }
        return value;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
}

 9、可编辑复合对象

public class A
{
    public A()
    {
        if (EndPoint == null)
        {
            EndPoint = new PGIPEndPoint
                {
                    IPAddress = "255.255.255.255",
                    Port = 65535
                };
        }
    }
    [TypeConverter(typeof(IPEndPointConverter))]
    public PGIPEndPoint EndPoint { get; set; }
}
public class IPEndPointConverter : ExpandableObjectConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return true;
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return true;
    }
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var result = ((string)value).Split(':');
        var ip = IPAddress.Parse(result[0]);
        var port = Convert.ToInt32(result[1]);
        if (port < 0 || port > 65535)
        {
            throw new Exception(string.Format("{0}要在0至65535之间。", port));
        }
        return new PGIPEndPoint
            {
                IPAddress = ip.ToString(),
                Port = port
            };
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        var result = (PGIPEndPoint)value;
        return string.Format("{0}:{1}", result.IPAddress, result.Port);
    }
}
public class PGIPEndPoint
{
    [TypeConverter(typeof(IPConverter))]
    public string IPAddress { get; set; }
    [TypeConverter(typeof(ZeroTo65535Converter))]
    public int Port { get; set; }
}

public class ZeroTo65535Converter : Int32Converter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        var result = Convert.ToInt32(value);
        if (result < 0 || result > 65535)
        {
            throw new Exception(string.Format("{0}要在0至65535之间。", result));
        }
        return result;
    }
}

public class IPConverter : StringConverter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return (IPAddress.Parse((string)value)).ToString();
    }
}

 10、属性的显示顺序

把PropertyGrid控件的PropertySort设置为NoSort可使属性以其被截取時的顺序显示。

11、去除工具栏

把ToolBarVisible设置为False。

原文地址:https://www.cnblogs.com/yao2yao4/p/3155700.html