代码之家  ›  专栏  ›  技术社区  ›  Jazimov

WinForms设计器和TableLayoutPanel智能标记自定义

  •  1
  • Jazimov  · 技术社区  · 6 年前

    我正在尝试自定义TableLayoutPanel Windows窗体控件的现有智能标记内容,以便在Windows窗体设计器中使用(我实现了一个设计器,它利用系统.组件模型.设计以及系统.Windows.Forms。设计名称空间)。无论提供什么方法作为解决方案,当我的控件被添加到visualstudio工具箱中时,以及当我的控件在visualstudio IDE中以设计模式放置在WinForm表面上时,它都必须起作用。

    我想做的是: 在设计模式下,窗体上的TableLayoutPanel控件实例显示一个装饰,单击该装饰时,显示由“操作”组成的智能标记面板,例如添加列、添加行、,等等(其中一些动作也以动词形式出现在属性网格下——我知道如何修改这些动词:我的问题只与智能标记动作列表有关。)

    我想做的是用我自己的一些项目修改TableLayoutPanel控件的设计时智能标记操作列表。

    不幸的是,要做到这一点,您必须将控件与自定义设计器相关联。但是,我不想使用自定义设计器或从ControlDesigner派生的设计器。我发现当我这样做的时候,我就失去了TableLayoutPanel控件提供的所有设计器功能——比如查看新行、新列以及能够将控件拖放到其客户机表面。我必须保留TableLayoutPanel的这种视觉设计时功能。

    如果我使用Designer属性将TableLayoutPanelDesigner类指定为设计器,那么我就走运了,因为该类被标记为internal( https://referencesource.microsoft.com/#System.Design/System/Windows/Forms/Design/TableLayoutPanelDesigner.cs ).

    如何利用WinForm TableLayoutPanel控件的现有设计器同时自定义其智能标记的操作列表?当然,这必须可以通过反射访问(但我不知道如何访问)。

    1 回复  |  直到 5 年前
        1
  •  4
  •   Reza Aghaei    5 年前

    TableLayoutPanelDesiner TableLayoutPanel 从零开始,因为你将失去所有当前的设计师功能。

    A真的很好 戏法 就是在设计时找到设计师并操纵设计师。看看这个 以及 背景色 新项目:

    enter image description here

    为此,您可以找到 表格布局面板 并对其进行操作。一个很好的观点是 OnHandleCreated IDesignerHost Site

    然后可以获取控件的当前操作列表,并创建一个包含所有这些操作项的新操作列表,并向列表中添加一些新操作项。

    MyTableLayoutPanel

    using System;
    using System.ComponentModel.Design;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;
    public class MyTableLayoutPanel : TableLayoutPanel
    {
        private IDesignerHost designerHost;
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            if (DesignMode && Site != null)
            {
                designerHost = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (designerHost != null)
                {
                    var designer = (ControlDesigner)designerHost.GetDesigner(this);
                    if (designer != null)
                    {
                        var actions = designer.ActionLists[0];
                        designer.ActionLists.Clear();
                        designer.ActionLists.Add(
                            new MyTableLayoutPanelActionList(designer, actions));
                    }
                }
            }
        }
    }
    

    MyTableLayoutPanel操作列表

    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Windows;
    using System.Windows.Forms.Design;
    public class MyTableLayoutPanelActionList : DesignerActionList
    {
        MyTableLayoutPanel control;
        ControlDesigner designer;
        DesignerActionList actionList;
        public MyTableLayoutPanelActionList(ControlDesigner designer, 
            DesignerActionList actionList) : base(designer.Component)
        {
            this.designer = designer;
            this.actionList = actionList;
            control = (MyTableLayoutPanel)designer.Control;
        }
        public Color BackColor
        {
            get { return control.BackColor; }
            set
            {
                TypeDescriptor.GetProperties(Component)["BackColor"]
                    .SetValue(Component, value);
            }
        }
        private void DoSomething()
        {
            MessageBox.Show("My Custom Verb added!");
        }
        public override DesignerActionItemCollection GetSortedActionItems()
        {
            var items = new DesignerActionItemCollection();
            foreach (DesignerActionItem item in actionList.GetSortedActionItems())
                items.Add(item);
            var category = "New Actions";
            items.Add(new DesignerActionMethodItem(this, "DoSomething", 
                "Do something!", category, true));
            items.Add(new DesignerActionPropertyItem("BackColor", "Back Color",
                category));
            return items;
        }
    }