【问题标题】:Form crashes when using visual inheritance使用视觉继承时表单崩溃
【发布时间】:2019-01-14 15:10:38
【问题描述】:

我想知道您是否可以在下面帮助我?

我有一个包含多个窗体的项目。这些表单中的大多数将使用相同的方法,因此,我创建了 BaseForm 并从它继承。

一切正常,但是当我在设计器中将几个文本框添加到从 BaseForm 继承的 Form1 时,Visual Studio 开始崩溃。现在我无法打开 Form1 设计器,因为每次执行此操作时 VisualStudio 都会崩溃。

请看下面我的基类和继承自 BaseForm 的 Form1。我做了一些研究,发现很多人建议不要在 Windows 窗体中使用视觉继承。

除了继承还有其他方法吗?还是我做错了什么? baseform和Form1都使用InitializeComponent()是不是有问题?

public partial class BaseForm : Form
{
    private List<Form> OpenForms = new List<Form>();

    public BaseForm()
    {
        ListOpenForms();
        CloseOpenForms();
        this.FormBorderStyle = FormBorderStyle.None;
        InitializeComponent();

        SetBackroundPicture();
        ShowPostionForm();
    }

    private void ListOpenForms()
    {
        foreach (Form frm in Application.OpenForms)
        {
            OpenForms.Add(frm);
        }
    }

    private void CloseOpenForms()
    {
        foreach (Form frm in OpenForms)
        {
            if (frm.Text != "MainMenu")
                frm.Close();
        }
    }

    private void ShowPostionForm()
    {
        this.MdiParent = MainMenu.MainForm;
        this.Dock = DockStyle.Fill;
        this.Show();
    }

    private void SetBackroundPicture()
    {
        this.BackgroundImage = global::OMSRoutine.Properties.Resources.BackgroundPlain;
        this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
    }

表格1:

public partial class Form1 : BaseForm
    {
        public Form2()
        {
            InitializeComponent();
        }
    }

【问题讨论】:

  • 首先调用初始化组件。
  • 不确定您使用该 OpenForms 列表实现了什么。如果您正在尝试关闭所有客户端窗体,则 MDIParent 窗体具有 MDIChildren 集合属性。在 ForEach 循环中修改集合时要小心,事情往往不会顺利进行。反向使用 for 循环来保留集合的索引顺序。
  • 我更改了顺序,BaseForm 现在是 InitializeComponent();然后 this.FormBorderStyle = FormBorderStyle.None;但它仍然不断崩溃。我想我应该初始化 Form1 的组件,然后调用 Baseform,但它不能像继承那样工作
  • 当你打开派生自BaseFormForm1时,BaseForm的构造函数就会运行,这不是你想要的。要详细了解设计师的工作方式,请查看this post

标签: c# winforms windows-forms-designer


【解决方案1】:

您可以编写扩展方法,而不是继承您的表单:

public static class FormExtension
{
    public static InitializeForm(this Form form)
    {
        form.ListOpenForms();
    }

    public static void ListOpenForms()
    {
        foreach (Form frm in Application.OpenForms)
        {
            OpenForms.Add(frm);
        }
    }

}

当调用MyForm1(之前继承自BaseForm)的构造函数时:

this.InitializeForm();

不知道您提供的方法是否有意义,但这是另一个问题。我的代码没有经过测试,但你明白了……

【讨论】:

    【解决方案2】:

    感谢您的回答。我修复了我的表单,但我发现在 baseform 包含背景图片的 Windows 表单上使用继承将无法正常工作。

    问题是继承的代码首先在设置背景、更改边框样式等的地方运行。

    在执行继承类的代码后,Form1 被初始化。初始化表单时,Visual Studio 执行这部分代码,修剪背景图片仅覆盖屏幕的一半 this.ClientSize = new System.Drawing.Size(1082, 509);

    【讨论】:

      【解决方案3】:

      对于遇到此问题的其他人,请参阅其他问题:

      Visual studio crashes when opening forms inheriting from a specific form in the project

      如果您的基本表单中有 Timer 执行使用某些未实例化成员的代码,VS 也可能崩溃。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-04
        • 2017-11-22
        • 1970-01-01
        • 2019-11-14
        • 2014-05-28
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多