自定义 ToolStrip 从 Designer.cs 文件中删除 PerfromLayout

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

假设我有一个

Form
并且它包含一个
ToolStrip
。在
Form1.Designer.cs
文件中,我可以看到以下行:

this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();

假设我使用以下代码生成自定义 ToolStrip:

[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
public class MyToolStrip : ToolStrip
{
}

参见 WinForms ToolStrip 在视觉继承中不可用

如果我现在在

MyToolStrip
中使用
ToolStrip
而不是
Form
,那么
this.toolStrip1.PerformLayout()
行将从设计器文件中删除。为什么?我怎样才能把它带回来,而不需要每次编辑我不应该做的设计器文件?

如果该行缺失,则某些控件的大小不正确,例如:

ToolStripComboBox

另请参阅 C#:ResumeLayout(true) 与 ResumeLayout(false) + PerformLayout() 的作用相同吗?

c# winforms windows-forms-designer toolstrip .net-4.6.2
1个回答
0
投票

前言:这是基于我的理解,您希望对 ToolStrip 控件使用视觉继承,但允许继承的表单修改 ToolStrip 的“Items”属性,该属性通常在派生表单中不可编辑。

警告:这是一项完整的黑客工作,我还没有评估实现用于获得所需结果的技巧的后果。

----------

正如评论中提到的,ControlDesigner类的属性

SerializePerformLayout
返回“false”,而ToolStripDesigner类的属性
SerializePerformLayout
返回“true”。 该属性在 ToolStripCodeDomSerializer 类的
Serialize
方法中使用(实际上该方法是从 ControlCodeDomSerializer 类继承的)。 具体在这段代码片段中:

if (HasAutoSizedChildren(control) || (controlDesigner is not null && controlDesigner.SerializePerformLayout))
{
   SerializePerformLayout(manager, csCollection, value);
}

由于无法覆盖

controlDesigner.SerializePerformLayout
,因此我们必须找到一种方法使
HasAutoSizedChildren(control)
评估为 true。 一种方法是将隐藏控件添加到 ToolStrip 的控件集合中。

public MyToolStrip() : base()
{
    Control c = new Control();
    c.Visible = false;
    c.MinimumSize = System.Drawing.Size.Empty;
    c.Size = System.Drawing.Size.Empty;
    c.AutoSize = true;
    Controls.Add(c);
}

通常,ToolStrip 不是父控件,而是从 ToolStripItem 类派生的组件。事实上,它的

ControlCollection
是只读的。 为了解决这个问题,我们需要重写
CreateControlsInstance
方法。

protected override Control.ControlCollection CreateControlsInstance()
{
  return  new ControlCollection(this);
}

总结一下:

    [Designer("System.Windows.Forms.Design.ControlDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    public class MyToolStrip : ToolStrip
    {
        public MyToolStrip() : base()
        {
            Control c = new Control();
            c.Visible = false;
            c.MinimumSize = System.Drawing.Size.Empty;
            c.Size = System.Drawing.Size.Empty;
            c.AutoSize = true;
            Controls.Add(c);
        }

        protected override Control.ControlCollection CreateControlsInstance()
        {
          return  new ControlCollection(this);
        }
    }

您仍然需要在基本表单的设计器中将 ToolStrip 的

Modifiers
属性设置为
Protected

© www.soinside.com 2019 - 2024. All rights reserved.