Winforms 控制表单

Posted

技术标签:

【中文标题】Winforms 控制表单【英文标题】:Winforms Controlling Forms 【发布时间】:2010-03-24 09:07:49 【问题描述】:

如何从 main () 控制我的所有表单

        Form1 frm1 = new Form1();
        Form1 frm2 = new Form1();
        Form1 frm3 = new Form1();

        Application.Run(frm1);  // This way form-control goes to the frm1.
                                // In frm1 i have to write
                                frm1.Clicked += ()=>frm2.Show;

        // I want the form-controlling style more explicitly
        // I dont want to use Application.Run()

        frm1.Show();
        frm1.Clicked += frm2.Show();

form.ShowDialog () 有很大帮助,但执行堆栈可能会溢出。 Form.Show 和 Form.Hide 方法在设置应用程序类时运行。 在 Application.Run (Form) 方式中,总有一个主窗体。我不想要这个。您在此问题中使用的任何其他方法

【问题讨论】:

我不明白你的问题。请准确说明您想要实现的目标。 你将不得不解释更多你想要做什么。 “控制所有表单”(如何控制它们?你想用它们做什么?)和“执行堆栈可能溢出”是什么意思。在您的伪代码中,Show 和 ShowDialog 之间没有区别,只是在您使用 ShowDialog 时执行将停止,直到表单关闭。 但是当我使用 showdialog 时,stacktrace 的长度开始变长。我可以看到此跟踪上的所有表单导航。它可能导致 *** 异常。 如果您想要的是没有“主表格”的情况,这是可能的,但您需要澄清问题,正如其他人所评论的那样。 ApplicationContext 继承 - 请参阅 here。 【参考方案1】:

您的问题是,您有四种形式。它们都应该并排存在,但是因为您将Form1 发给了主人,所以您遇到了一些问题。

要解决这个问题,您需要另外一个FormMaster 来解决这四个问题。这个将从Application.Run()开始。现在这个表单可以是Visible = false,但在它的构造函数中,您可以创建所有四个表单并决定如何将它们粘合在一起,首先显示哪个以及在什么情况下关闭整个应用程序。

【讨论】:

表单控制逻辑应该写在主表单中。没有其他办法 @jacklondon 有正确的方法:从ApplicationContext 继承。见here。 @ZevSpitz:使用隐藏的主表单来编排子表单与使用相同的应用程序上下文有什么区别?我不认为其中任何一个是正确错误。只有两种不同的方法可以达到相同的效果,而没有任何其他缺点,使一种比另一种更好。 为工作使用正确的工具不是很重要吗?表单表示构成应用程序用户界面的窗口或对话框。 (MSDN) 并且应该用于此目的。有时可能有必要诉诸丑陋的隐藏表单,这些隐​​藏表单从未显示过,但这里没有。【参考方案2】:

通常的方式是使用event handlers。

【讨论】:

【参考方案3】:

我能理解的是你有几个WinForms,你想要一些主窗体来控制它们?好吧,如果我的理解/假设是正确的,那么关于控制如下?

public partial class Form3 : Form

    private void Form3_Load(object sender, EventArgs e)
    
        Demo();
    

    MyMainForm main = new MyMainForm(); //Your actual form
    private void Demo()
    
        main.Click += new EventHandler(main_Click);
        main.ShowDialog();
    

    void main_Click(object sender, EventArgs e)
    
        MyNotificationForm notify = new MyNotificationForm();//Your notification form
        notify.Name = "notify";
        notify.Click += new EventHandler(notify_Click);
        notify.ShowDialog(main);
    

    void notify_Click(object sender, EventArgs e)
    
        MyWarningForm warning = new MyWarningForm();//Your warning form
        warning.Click += new EventHandler(warning_Click);
        warning.ShowDialog(main.ActiveMdiChild);
    

    void warning_Click(object sender, EventArgs e)
    
        ((Form)sender).Close(); //Click on form would close this.
    

以下是我将如何实现这些类。

public class CBaseForm : Form
 public CBaseForm()  this.Text = "Main App";  

public class MyWarningForm : CBaseForm
 public MyWarningForm()  Label lbl = new Label(); lbl.Text = "Warning Form"; this.Controls.Add(lbl);  

public class MyNotificationForm : CBaseForm
 public MyNotificationForm()  Label lbl = new Label(); lbl.Text = "Notification Form"; this.Controls.Add(lbl);  

public class MyMainForm : CBaseForm
 public MyMainForm()  Label lbl = new Label(); lbl.Text = "Controller Form"; this.Controls.Add(lbl);  

而你MainForm 会按照惯例开始

Application.Run(new Form3());

如果我把你的问题拖到 180 度,请告诉我!

【讨论】:

-1。继承自 ApplicationContext - 请参阅 here。

以上是关于Winforms 控制表单的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# Winforms 表单之间转换?

根据表单大小设置 splitContainer 属性大小 C# WinForms

WinForms 中的每个表单都有自己的线程吗?

在winforms中绘制水平分隔线[重复]

在运行时更改 winforms 控件

WinForms 编程 - 模态和非模态表单问题