的WinForms设计师和TableLayoutPanel中的智能标签定制

问题描述 投票:1回答:1

我想自定义一个TableLayoutPanel的Windows现有的智能标记内容窗体控件在Windows窗体设计器使用(我实施了利用由System.ComponentModel.Design和System.Windows.Forms.Design暴露的WinForms设计器功能设计师命名空间)。无论方法是提供一个解决方案,它有也工作时,我的控件添加到Visual Studio工具箱,当我控制在Visual Studio IDE被放置在一个WinForm面的设计模式,同时。

这里就是我想要做的事:在设计模式中,窗体上的TableLayoutPanel控件实例显示的装饰,点击后,提出了“动作”,如添加列,添加行等(构成的智能标记面板其中一些操作也出现属性网格下动词 - 我知道如何修改这些动词:我的问题与只有智能标记动作列表做)。

我想要做的是与我自己的一些物品修改TableLayoutPanel控件的设计时智能标记动作列表。

不幸的是,似乎要做到这一点,你必须用自定义设计的控制关联。不过,我不希望使用自定义设计或者某个自ControlDesigner派生之一。我发现,当我这样做,我失去了所有的设计功能TableLayoutPanel控件报价 - 如看到新的行,列和能够拖动和拖放控件拖到其客户面。我必须保留TableLayoutPanel中这样的可视化设计时功能。

如果我使用Designer属性来指定TableLayoutPanelDesigner类作为设计师,那么我的运气,因为该类被标记为内部(https://referencesource.microsoft.com/#System.Design/System/Windows/Forms/Design/TableLayoutPanelDesigner.cs)。

我如何可以利用的WinForm的TableLayoutPanel控件现有的设计师又还可以自定义其智能标签的操作列表?当然这必须是使用反射访问(但我无法弄清楚如何)。

c# .net winforms windows-forms-designer tablelayoutpanel
1个回答
4
投票

TableLayoutPanelDesiner是内部的,有依赖于其他内部类,你不能继承它。而且,这不是一个好主意,从头开始创建TableLayoutPanel一个新的控件设计,因为你将失去所有的现任设计师的功能性。

一个真正好的诀窍是找到设计师和操纵在设计时设计师。看看做些什么!和背景色新项目:

enter image description here

要做到这一点,你可以找到你TableLayoutPanel在设计时设计师和操纵它。好的一点是在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));
                }
            }
        }
    }
}

MyTableLayoutPanelActionList

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.