【问题标题】:How to open form from Child Form and show in main form panel如何从子表单打开表单并在主表单面板中显示
【发布时间】:2021-01-27 19:38:45
【问题描述】:

我目前正在使用 C# Visual Studio 2017 开发一个 Windows 窗体应用程序,并决定使用教程 seen here 实现侧面板菜单。

单击时显示子表单非常有用,但是我想知道如何在子表单代码中将当前子表单替换为新的子表单。 IE。如何在子表单代码中访问主表单。

private Form activeForm = null;
    private void openChildForm(Form childForm)
    {
        if (activeForm != null)
            activeForm.Close();
        activeForm = childForm;
        childForm.TopLevel = false;
        childForm.FormBorderStyle = FormBorderStyle.None;
        childForm.Dock = DockStyle.Fill;
        childFormPanel.Controls.Add(childForm);
        childFormPanel.Tag = childForm;
        childForm.BringToFront();
        childForm.Show();
    }

这就是在主窗体中打开子窗体的方式。如何通过子表单访问此方法? 我相信这可能会让人很困惑,但如果您快速观看视频,您就会明白我的意思。

谢谢!

【问题讨论】:

  • 在子窗体中创建一个事件,您可以在主窗体中绑定到该事件。当孩子请求更改时,主窗体可以处理更改。
  • 听起来和我应该做的完全一样,你能指出我如何将事件绑定到主窗体中的正确方向吗?

标签: c# visual-studio winforms menu


【解决方案1】:

可以使用保留主窗体实例的静态类。当您加载主表单时,请在 FormController 类中设置 MainForm 静态属性。然后从您的子表单调用 FormControll.openChildForm(...);

public static FormController{
    public static Form MainForm {get;set;}
    
    private static Form activeForm = null;
    public static void openChildForm(Form childForm)
    {
       if (activeForm != null)
          activeForm.Close();
       activeForm = childForm;
       MainForm.childForm.TopLevel = false;
       MainForm.childForm.FormBorderStyle = FormBorderStyle.None;
       MainForm.childForm.Dock = DockStyle.Fill;
       MainForm.childFormPanel.Controls.Add(childForm);
       MainForm.childFormPanel.Tag = childForm;
       MainForm.childForm.BringToFront();
       MainForm.childForm.Show();
     }
}

然后在您的子表单中,您可以调用该静态类来更改表单。

public class ChildForm{
    private void btn_click(...){
        FormController.openChildForm(<newChildForm>);
    }
}

【讨论】:

  • 我在哪里保存 activeForm 变量?
  • 在 FormsController 中。这将是一个私有静态变量,在 openChildForm 方法中被检查(和设置)。
【解决方案2】:

你可以使用事件来处理这个:

步骤 1) 创建一个继承自 Form 的新类。这将是您所有孩子表格的基类。您可以调用此 ChildForm(继承自)Form。

第 2 步)定义一个新的公共事件,您可以从更改子表单的功能中绑定到该事件。

可能看起来像这样:

public event EventHandler OnRequestChildChange;

第 3 步)在您想要请求更改的孩子中,您可以致电:

OnRequestChildChange?.Invoke(null); //这也会传入您的参数,因此您可以创建一个事件,允许您传入自定义参数并传入表单的名称或类型,并在您的事件处理程序中有一个 switch 语句。

自定义事件: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-publish-events-that-conform-to-net-framework-guidelines

第 4 步)绑定到主函数中的事件

private ChildForm activeForm = null;
private void openChildForm(ChildForm childForm)
{
  if (activeForm != null){
    activeForm.OnRequestChildChange -= Child_RequestChange;
    activeForm.Close();
  }

  activeForm = childForm;
  activeForm.OnRequestChildChange += Child_RequestChange;
  childForm.TopLevel = false;
  childForm.FormBorderStyle = FormBorderStyle.None;
  childForm.Dock = DockStyle.Fill;
  childFormPanel.Controls.Add(childForm);
  childFormPanel.Tag = childForm;
  childForm.BringToFront();
  childForm.Show();
}

第 5 步)创建事件处理程序“Child_RequestChange”,它将通过创建新实例或拉取所需新表单的本地实例并调用上述方法来处理子请求时交换表单。

【讨论】:

  • 我的所有表单现在应该是这样的吗? public partial class CabinetForm : ChildForm
  • 是的,它们现在将引用您的基类。
  • 我试过了,但是我无法在设计器模式下查看表单
猜你喜欢
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多