[C#.NET][Winform][User Control] 自订控件的智能标签-ControlDesigner / User Control of Smart Tag-ControlDesigner

[C#.NET][Winform][User Control] 自订控件的智能标签-ControlDesigner / User Control of Smart Tag-ControlDesigner


这次我希望能达成下面效果,控件会有一个小箭头出现,可以由此设定控件属性

201072212655130[1]

1.在System.Windows.Forms.Design 命名空间的 ControlDesigner 类:用来建立智能面版的类

2.在System.ComponentModel.Design 命名空间 里开头为 DesignerAction,是用来决定智能面版清单模式。

以下是实现DesignerActionXXX重要类。

DesignerActionList:建立一个智能面板清单。

DesignerActionService:建立一个服务,管理收集DesignerActionItem的类

DesignerActionItemCollection:收集DesignerActionXXX系列的集合

DesignerActionUIService :管理智能面板UI。

DesignerActionItem:它是一个基底类,表示一个智能面板的项目。

DesignerActionTextItem:表示智慧面板上的文字叙述,继承 DesignerActionItem。

DesignerActionPropertyItem:表示智能面板的属性,继承 DesignerActionItem。

DesignerActionMethodItem:表示智能面板上建立一个方法,点击这个项目会去执行相应的方法,继承 DesignerActionItem。

DesignerActionHeaderItem:表示智能面板分类标题,继承 DesignerActionItem。


image

上图我所要表达的是:

ControlDesigner里面装了一个DesignerActionList,DesignerActionItemCollection 收集著UI所要呈现的项目。

3.在 System.ComponentModel命名空间 底下的 PropertyDescriptor 方法:用它来处理智能面版的UI画面更新

4.DesignerActionUIService.Refresh():更新智能面版方法

了解各类的方法后接下来就可以开始实践;开始之前先加入System.Designer参考,并导入命名空间

1.建立使用者控件项目,PropertySmartTag类继承UserControl,并为类加入控件及属性

1-1.加入控件label1及checkBox1

image

1-2.加入以下属性

//自订控件
public partial class PropertySmartTag : UserControl
{
    public PropertySmartTag()
    {
        InitializeComponent();
    } 

    private Size _FormSize;
    /// 
    /// 改变Form尺寸
    /// 
    public Size FormSize
    {
        get
        {
            return _FormSize;
        }
        set
        {
            _FormSize = value;
            base.Size = _FormSize;
        }
    }
    /// 
    /// 覆写颜色
    /// 
    public override Color BackColor
    {
        get { return base.BackColor; }
        set { base.BackColor = value; }
    }
    /// 
    /// 变更checkBox控制是否勾选
    /// 
    private bool _IsSelect;
    public bool IsSelect
    {
        get { return _IsSelect; }
        set
        {
            _IsSelect = value;
            this.checkBox1.Checked = _IsSelect;
        }
    }
    /// 
    /// Label控件内容
    /// 
    public string LabelText
    {
        get { return this.label1.Text; }
        set { this.label1.Text = value; }
    } 

    /// 
    /// 变更Label控件字型
    /// 
    private Font _TextFont;
    public Font TextFont
    {
        get
        {
            if (_TextFont == null)
            {
                _TextFont = new Font(this.Font, FontStyle.Bold);
            }
            return _TextFont;
        }
        set
        {
            _TextFont = value;
            this.label1.Font = _TextFont;
        }
    }
}

2.建立CreateControlDesigner 类,继承System.Windows.Forms.Design.ControlDesigner。

//建立控件设计类
internal class CreateControlDesigner : System.Windows.Forms.Design.ControlDesigner
{
    private DesignerActionListCollection _ActionLists;
    public override DesignerActionListCollection ActionLists
    {
        get
        {
            if (null == _ActionLists)
            {
                //加入智能面版模式
                _ActionLists = new DesignerActionListCollection();
                _ActionLists.Add(new CustomControlActionList(this.Component));
            }
            return _ActionLists;
        }
    }
}

3.建立CustomControlActionList类,继承System.ComponentModel.Design.DesignerActionList。

//定义智能面版模式类
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class CustomControlActionList : System.ComponentModel.Design.DesignerActionList
{
    //建立面版UI服务
    private PropertySmartTag _PropertySmartTag;
    private DesignerActionUIService _DesignerActionUIService = null;//我主要用来更新面版UI,若不更新可以省略。
    public CustomControlActionList(IComponent component)
        : base(component)//建构子
    {
        this._PropertySmartTag = component as PropertySmartTag;//表示绑定到"PropertySmartTag使用者控件"类
        this._DesignerActionUIService = GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
    } 

    //更新自订控件的属性
    private PropertyDescriptor GetPropertyByName(String PropertyName)
    {
        PropertyDescriptor prop;
        prop = TypeDescriptor.GetProperties(_PropertySmartTag)[PropertyName];
        if (null == prop)
            throw new ArgumentException("找不到此属性名称!", PropertyName);
        else
            return prop;
    }
    //定义智能面版的属性,面版属性会与绑定的"PropertySmartTag使用者控件"属性同步
    public Size FormSize
    {
        get { return _PropertySmartTag.Size; }
        set { GetPropertyByName("FormSize").SetValue(_PropertySmartTag, value); }
    }
    public Color BackColor
    {
        get { return _PropertySmartTag.BackColor; }
        set { GetPropertyByName("BackColor").SetValue(_PropertySmartTag, value); }
    }
    public string LabelText
    {
        get { return _PropertySmartTag.LabelText; }
        set { GetPropertyByName("LabelText").SetValue(_PropertySmartTag, value); }
    }
    public bool IsSelect
    {
        get { return _PropertySmartTag.IsSelect; }
        set { GetPropertyByName("IsSelect").SetValue(_PropertySmartTag, value); }
    }
    public Font TextFont
    {
        get { return _PropertySmartTag.TextFont; }
        set { GetPropertyByName("TextFont").SetValue(_PropertySmartTag, value); }
    }
    //方法
    public void ChangeText()
    {
        GetPropertyByName("LabelText").SetValue(_PropertySmartTag, "Call Method");
        _DesignerActionUIService.Refresh(this.Component);//更新智能面版
    }
    //设计智能面版项目
    public override DesignerActionItemCollection GetSortedActionItems()
    {
        DesignerActionItemCollection items = new DesignerActionItemCollection(); 

        //Define static section header entries.
        items.Add(new DesignerActionHeaderItem("Custom Category"));
        items.Add(new DesignerActionPropertyItem("BackColor", "Back Color", "Custom Category", "选择背景颜色"));
        items.Add(new DesignerActionPropertyItem("FormSize", "Form Size", "Custom Category", "选择尺寸"));
        items.Add(new DesignerActionPropertyItem("LabelText", "Label Text", "Custom Category", "随便输入"));
        items.Add(new DesignerActionPropertyItem("IsSelect", "Select", "Custom Category", "是否选择"));
        items.Add(new DesignerActionPropertyItem("TextFont", "Text Font", "Custom Category", "选择字型")); 

        items.Add(new DesignerActionTextItem("Custom Smart Tag", "Custom Category"));
        items.Add(new DesignerActionMethodItem(this, "ChangeText", "Change Text", "Custom Category", "调用方法", true));
        return items;
    }
}

4.在PropertySmartTag类定义Designer attribute

[Designer(typeof(CreateControlDesigner))]
//自订控件
public partial class PropertySmartTag : UserControl
{

}

5.加入WinForm项目,用来测试PropertySmartTag控件

执行结果如下

image

接下来我们再来看VS帮我们产生出了哪些程序

这次我们并没有帮属性定义Attribute [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)],可是VS还是帮我们把Code生出来了。

另外,使用DesignerActionMethodItem类的属性按右键会出现。

范例下载:

VB_UserControl_SmartTags.zip

CS_UserControl_SmartTags.zip

参考数据

http://www.codeproject.com/KB/dialog/usercontrolsmarttag.aspx

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

2010~2017 C# 第四季