C# 在表单启动期间动态移动和初始化表单设计器创建的表单元素

C# 在表单启动期间动态移动和初始化表单设计器创建的表单元素,c#,winforms,forms,visual-studio-2010,visual-studio,C#,Winforms,Forms,Visual Studio 2010,Visual Studio,我正在使用VisualStudio表单设计器为我的Windows桌面应用程序最初布局表单。以下是该表单自动生成的InitializeComponent()方法的内容片段: /。。。 this.Controls.Add(this.menuStrip1); this.Controls.Add(this.panel1); this.main menustrip=this.menuStrip1; this.Name=“Form1”; this.Text=“Form1 Title”; this.menuS

我正在使用VisualStudio表单设计器为我的Windows桌面应用程序最初布局表单。以下是该表单自动生成的
InitializeComponent()
方法的内容片段:

/。。。
this.Controls.Add(this.menuStrip1);
this.Controls.Add(this.panel1);
this.main menustrip=this.menuStrip1;
this.Name=“Form1”;
this.Text=“Form1 Title”;
this.menuStrip1.resumeloayout(false);
此.menuStrip1.PerformLayout();
此.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
// ...
我想做的是注入一个过程,在启动过程中移动、调整和初始化窗体及其几个控件。我相信,在第一次调用
ResumeLayout()
之前,最适合这样做

方便的是,我发现我可以覆盖我的表单:

公共重写字符串文本
{
设置
{
如果(!this.formInitialized)
{
剂量特异性初始化();
this.formInitialized=true;
}
base.Text=值;
}
}
虽然我发现这种方法确实有效,但它让我觉得可能有更好的方法来实现我的目标。是否有更好的方法,最好是不需要更多努力的方法

更新:正如我在回复@Grant Winney答案的评论中所指出的,我知道我可以在调用
InitializeComponent()
之后在表单构造函数中进行初始化。但我希望避免重复所有对
SuspendLayout()
ResumeLayout()
(请参阅
InitializeComponent()
的内部内容)的调用,因为我相信这会降低性能,并可能导致将来的维护难题

不幸的是,仅仅在父窗体上调用
SuspendLayout()
ResumeLayout()
是不够的。以下是@Grant引用的原因(见第三段):

请记住,SuspendLayout只会阻止布局事件发生 为该特定控件执行。如果将控件添加到 面板,例如,必须调用SuspendLayout和ResumeLayout 面板,而不是父窗体

两个想法:

  • 您可以从构造函数中调用一个方法来移动控件。这似乎不太“黑客”,因为它不依赖于正在设置的表单上某些其他属性的副作用。

    (此外,如果将来有人修改代码以在运行时更改窗口文本,他们会无意中再次运行初始化代码。)

  • 少用这个。当窗体在设计器中是单向的,然后在运行时是12种不同方式中的一种时,维护就会变得非常困难


  • 1.是的,这是我尝试的第一种方法。但是,我发现我需要重复出现在
    InitializeComponent()
    中的对
    SuspendLayout()和
    ResumeLayout()的所有调用。2.我的表单有几个面板,在任何给定时间都只能看到其中一个。在designer中,我布置了所有面板,然后折叠主窗体,并在启动时显示第一个面板。更多:每个面板在窗体上占据相同的位置。我现在做的有点像个巫师。我在左边有
    TreeView
    ,它驱动表单的其余部分。点击
    树状视图中的一个节点
    会显示一个与该特定类型节点相关的面板。是的,我认为最大限度地减少未来的维护和潜在的“意外因素”!当然,一种可能性是完全放弃使用设计器,完全以编程方式构建表单。但我使用了设计师,因为我相信它为我节省了很多工作!1.对于我的表单,
    InitializeComponent()
    挂起并恢复以下所有控件:表单、面板、GroupBox、菜单提示、ToolStrip和StatusStrip。这导致人们相信,仅仅暂停和恢复父窗体本身可能是不够的。但是是吗?2.说得好!但是,我应该能够通过在表单上引入私有
    Boolean
    成员变量,比如
    m\u FormInitialized
    ,只允许进行一次特殊处理。谢谢你的链接。2.同意。就像我在这种情况下经常做的那样,我在代码中添加了大量的注释,说我的方法有点像黑客,还有一些词表明了我的动机。当然,我也在等待其他可能即将到来的答案。:-)
    public class MyForm : Form
    {
        public MyForm()
        {
            InitializeComponent();
    
            DoSpecialFormInitialization();
        }
    }