我想自定义一个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控件现有的设计师又还可以自定义其智能标签的操作列表?当然这必须是使用反射访问(但我无法弄清楚如何)。
TableLayoutPanelDesiner
是内部的,有依赖于其他内部类,你不能继承它。而且,这不是一个好主意,从头开始创建TableLayoutPanel
一个新的控件设计,因为你将失去所有的现任设计师的功能性。
一个真正好的诀窍是找到设计师和操纵在设计时设计师。看看做些什么!和背景色新项目:
要做到这一点,你可以找到你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;
}
}