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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM