• WinForm: Custom Control's Custom Designer and Smart Tag


    要给自定义控件加上自定义的设计器, 首先得写个Designer类, 比如下面的StackPanelDesigner:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms.Design;
    using System.ComponentModel.Design;

    namespace Dah.Framework.Windows.Design
    {
        
    internal class StackPanelDesigner : ParentControlDesigner // 这个类在System.Design.dll里, 一般的控件Designer可以继承ControlDesigner..
        {
            DesignerActionListCollection _actionLists;

            
    public override SelectionRules SelectionRules
            {
                
    get
                {
                    
    if (TheStackPanel.AutoSize) // 如果AutoSize
                    {
                        
    return SelectionRules.Moveable; // 则只能移动, 不能手动改变大小
                    }
                    
    else // 否则可以改变大小
                    {
                        
    return SelectionRules.Moveable | SelectionRules.AllSizeable; 
                    }
                }
            }

            
    public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
            {
                
    get
                {
                    
    if (_actionLists == null)
                    {
                        _actionLists 
    = new DesignerActionListCollection();
                        
    // 给 Smart Tag 添加 StackPanelActionList 里的选项
                        _actionLists.Add(new StackPanelActionList(this.Component));
                        
    // 给 Smart Tag 添加 LinearGradientPanelActionList 里的选项 , 因为 StackPanel 继承了 LinearGradientPanel 
                        _actionLists.Add(new LinearGradientPanelActionList(this.Component));
                    }
                    
    return _actionLists;
                }
            }

            
    private StackPanel TheStackPanel
            {
                
    get
                {
                    
    return (StackPanel)Control; // Designer 所 Design 的 Control
                }
            }
        }
    }

    如果要加上自己的SmartTag就还得写ActionList类, 如下面的StackPanelActionList:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;

    namespace Dah.Framework.Windows.Design
    {
        
    /// <summary>
        
    /// 定义了 StackPanel 的 Smart Tag 选项
        
    /// </summary>
        internal class StackPanelActionList : DesignerActionList
        {
            
    private StackPanel _stackPanel;

            
    public StackPanelActionList(IComponent component)
                : 
    base(component)
            {
                
    this._stackPanel = component as StackPanel;
            }

            
    private PropertyDescriptor GetPropertyByName(String propName)
            {
                PropertyDescriptor prop;
                prop 
    = TypeDescriptor.GetProperties(_stackPanel)[propName];
                
    if (null == prop)
                    
    throw new ArgumentException("Matching StackPanel property not found!", propName);
                
    else
                    
    return prop;
            }

            
    private void SetValue(string propertyName, object value)
            {
                GetPropertyByName(propertyName).SetValue(_panel, value);
            }

            
    //要有哪些属性的选项, 都得这样写一遍
            public bool AutoSize
            {
                
    get { return _stackPanel.AutoSize; }
                
    set { SetValue("AutoSize", value); }
            }

            
    public bool CenterAlign
            {
                
    get { return _stackPanel.CenterAlign; }
                
    set { SetValue("CenterAlign", value); }
            }

            
    public StackPanelOrientation Orientation
            {
                
    get { return _stackPanel.Orientation; }
                
    set { SetValue("Orientation", value); }
            }

            
    //这个方法在下面用到了, 可以用来调用控件的方法
            public void RefreshChildrenPosition()
            {
                _stackPanel.RefreshChildrenPosition();
            }

            
    //这个方法指定了Smart Tag到底有哪些选项
            public override DesignerActionItemCollection GetSortedActionItems()
            {
                DesignerActionItemCollection items 
    = new DesignerActionItemCollection();

                
    string headerName = "StackPanel Options";

                
    //添加一个选项 Category
                items.Add(new DesignerActionHeaderItem(headerName));

                
    //下面的各种选项都属于这个Category, 用headerName来指定
                items.Add(new DesignerActionPropertyItem("AutoSize""Auto Size", headerName));
                items.Add(
    new DesignerActionPropertyItem("CenterAlign""Center Align", headerName));
                items.Add(
    new DesignerActionPropertyItem("Orientation""Orientation", headerName));

                
    //上面三个都是控件属性的设置, 这个则可以给Smart Tag添加一个LinkButton来执行某些方法
                
    //this, 说明了"RefreshChildrenPosition"这个方法在这个类中实现
                items.Add(new DesignerActionMethodItem(this"RefreshChildrenPosition""Refresh children position", headerName));

                
    return items;
            }
        }
    }

    准备工作完毕, 给自定义控件加个DesignerAttribute就O了~:
        [Designer(typeof(Dah.Framework.Windows.Design.StackPanelDesigner))]
        
    public class StackPanel : LinearGradientPanel
        {
            
    public event EventHandler ContentMarginChanged;

    看看我们美丽的自定义Designer和Smart Tag吧~

    久不发文... 仅此灌水一篇~
    更多的有关如何扩展控件设计时行为的文章在MSDN Library:
    http://msdn2.microsoft.com/en-us/library/37899azc.aspx
  • 相关阅读:
    ORA-28040: No matching authentication protocol
    kettle增量抽取数据--高效抽取方式
    为什么MySQL的索引要使用B+树而不是其它树形结构?比如B树?
    echarts饼图指示线文字换行
    数据库概论
    Java学习笔记
    案例分析
    软件工程作业3
    软件工程作业2
    软件工程作业1
  • 原文地址:https://www.cnblogs.com/Dah/p/630212.html
Copyright © 2020-2023  润新知