[C#.NET][VB.NET][Winform][User Control] 自订控件的自订属性编辑窗口 / User Control of Custom Properties Editor

[C#.NET][VB.NET][Winform][User Control] 自订控件的自订属性编辑窗口 / User Control of Custom Properties Editor


这次我们必须要使用到基底类: UITypeEditor

使用这个类我们必须要覆写以下两个方法

1.EditValue:处理使用者界面、使用者输入处理和值的设定。也就是在这个方法实例化你所要处理的窗口,在这里我们有两种窗口的弹出呈现方式可以用,IWindowsFormsEditorService 界面

  1-1.DropDownControl(Control control) :下拉式清单的方式呈现。

  1-2.ShowDialog(Form dialog) :弹出窗口的方式呈现。

2.GetEditStyle :以通知编辑器模式的属性窗口,也就是选择编辑风格,UITypeEditorEditStyle 枚举类型

   2-1 UITypeEditorEditStyle.Modal:显示下拉菜单按钮。

   image

   2-2 UITypeEditorEditStyle.DropDown:显示(...) 按钮。

   image

   2-3 UITypeEditorEditStyle.None:没有交互界面。

了解要做什么之后就可以开始来写code,首先建立一个UserControl项目名为myUITypeEditor 并继承 UITypeEditor,覆写EditValue、GetEditStyle方法。

public class myUITypeEditor : UITypeEditor
{
    private Size DataSize;//用来存放窗口读到的值
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService EditorService = null;
        if (context != null && context.Instance != null && provider != null)
        {
            //建立编辑服务
            EditorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            //读取自订窗口的值
            PropertyListEditor ListEditorControl;
            PropertyFormEditor FormEditorControl;
            if (DataSize != null)
            {
                ListEditorControl = new PropertyListEditor(DataSize);
                FormEditorControl = new PropertyFormEditor(DataSize);
            }
            else
            {
                ListEditorControl = new PropertyListEditor(new Size(0, 0));
                FormEditorControl = new PropertyFormEditor(new Size(0, 0));
            }
            //建立编辑弹跳画面
            //法一:下拉清单
            //EditorService.DropDownControl(ListEditorControl);//画面弹跳方式
            //DataSize = ListEditorControl.size;
            //法二:窗口
            EditorService.ShowDialog(FormEditorControl);//画面弹跳方式
            DataSize = FormEditorControl.size;
            return DataSize;
        }
        else
        {
            return null;
        }
    } 

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        if (context != null && context.Instance != null)
        {
            return UITypeEditorEditStyle.Modal;
            //return UITypeEditorEditStyle.DropDown;
            //return UITypeEditorEditStyle.None;
        }
        return base.GetEditStyle(context);
    }
}

PS.ListEditorControl及FormEditorControl是两种不同的呈现方式,择一使用

接下来开始来刻我们所要呈现的UI,加入新的项目,分别加入一个Winform及一个UserControl项目

UserControl:PropertyListEditor

image

internal partial class PropertyListEditor : UserControl
{
    private Size _size;
    public Size size
    {
        get { return _size; }
        set { _size = value; }
    }
    public PropertyListEditor()
    {
        InitializeComponent();
    } 

    public PropertyListEditor(Size size)
    {
        InitializeComponent();
        this.size = size;
    } 

    private void PropertyListEditor_Load(object sender, EventArgs e)
    {
        if (_size != null)
        {
            this.txtWidth.Text = _size.Width.ToString();
            this.txtHeight.Text = _size.Height.ToString();
        }
    } 

    private void PropertyListEditor_Leave(object sender, EventArgs e)
    {
        if (this.txtWidth.Text != "" && this.txtHeight.Text != "")//判断输入的内容,我懒的写....
            _size = new Size(Convert.ToInt16(txtWidth.Text), Convert.ToInt16(txtHeight.Text));
    }
}

Winform:PropertyFormEditor

image

internal partial class PropertyFormEditor : Form
{
    private Size _size;
    public Size size
    {
        get { return _size; }
        set { _size = value; }
    }
    public PropertyFormEditor()
    {
        InitializeComponent();
    }
    public PropertyFormEditor(Size size)
    {
        InitializeComponent();
        this.size = size;
    }
    private void PropertyFormEditor_Load(object sender, EventArgs e)
    {
        if (_size != null)
        {
            this.txtWidth.Text = _size.Width.ToString();
            this.txtHeight.Text = _size.Height.ToString();
        }
    } 

    private void PropertyFormEditor_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (this.txtWidth.Text != "" && this.txtHeight.Text != "")//判断输入的内容,我懒的写....
        {
            _size = new Size(Convert.ToInt16(txtWidth.Text), Convert.ToInt16(txtHeight.Text));
        }
    }
}

我将两种呈现方式都写出来,不过这两个UI的程序都一模一样,不同的是当输入数据完毕窗口关闭的事件触发不一样

UserControl是用Leave事件把窗口所输入的值写到字段里,而Winform是用FormClosing事件;以及它们所继承的类也不同

最后这一个公开类里设定我们要的属性

public partial class UserControlType : UserControl
{
    public UserControlType()
    {
        InitializeComponent();
    }
    private Size _size = new Size();
    [Category("A Test")]
    [Editor(typeof(myUITypeEditor), typeof(UITypeEditor))]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Size size
    {
        get { return _size; }
        set { _size = value; }
    }
}

然后我们再加入一个新的Winform项目,把我们刚建立好的控件拖曳到Form里,并使用propertyGrid控件来观察我们所建立的size属性

image

image

Note:用窗口跳出必需要处理一下他出现的位置,这是本范例没有处理的。

范例下载

CS_UserControl_UITypeEditor.zip

VB_UserControl_UITypeEditor.zip

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

2010~2017 C# 第四季