首页 > 解决方案 > C#继承在运行时设置了变量的用户控件

问题描述

我有一个主窗体,它充当一堆不同用户控件的“向导”。我有一个具有相对基本操作的用户控件,并且我正在尝试创建一个继承此基本用户控件的新用户控件。

但是,基本用户控件有一个包含主窗体的变量(因此用户控件可以访问主窗体中的向导控件功能)。当我创建一个新的“继承的用户控件”时,设计器抱怨对 main for 的引用尚未设置为对象的实例。当我创建基本用户控件的实例时,我在运行时设置了对 MainForm 的引用。

有没有办法使这项工作?下面是一些演示我的问题的简化代码。

MainForm.cs:

public partial class MainForm : Form
{
    public string exampleString = "From MainForm";

    public MainForm()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        BaseControl base = new BaseControl();
        base.mainForm = this;
    {

}

BaseControl.cs

public partial class BaseControl : UserControl
{
    public MainForm mainForm { get; set;}

    public TestPanel()
    {
        InitializeComponent();
        string needed = mainForm.exampleString;    //Object reference not set to an instance of an object here
    }
}

因此,当我尝试创建一个通过并选择 BaseClass 继承 BaseControl 的用户控件时,设计人员在 BaseControl.csSolution -> Add -> New Item -> Inherited User Control中的行中抱怨“对象引用未设置为对象的实例”错误。string needed = mainForm.exampleString

对此的任何帮助将不胜感激。希望这是足够的信息,让您了解我想要做什么。

谢谢。

标签: c#.netwinformsinheritancereference

解决方案


您共享的代码在运行时和设计时都不起作用。

您尝试mainForm.exampleString在构造函数中使用BaseControlwhilemainForm将在创建BaseControl.

在这种情况下,特别是当您希望获得设计时支持时,您可以从ISupportInitializeinterface 派生并覆盖BeginInitand EndInit

例子

以下控件实现ISupportInitialize。如果您在窗体上放置控件的实例,在运行时,它会尝试查找父窗体,并且如果它MainForm尝试使用以下公共成员MainForm

using System.ComponentModel;
using System.Windows.Forms;
public class MyControl : Control, ISupportInitialize
{
    public void BeginInit()
    {
    }

    public void EndInit()
    {
        var parent = this.FindForm() as MainForm;
        if (parent != null)
        {
            //Access to MainForm members
        }
    }
}

这只是一个展示如何使用的示例ISupportInitialize。实际上,依赖于特定类型的父表单并不是一个好主意。Jimi 的评论中已经提到的一个更好的主意是依赖接口。例如,您可以ISomeInterface在您的控件中有一个属性。该接口应包含您希望为控件的父级拥有的方法或属性。然后以某种形式实现接口。然后在运行时或设计时删除控件的实例后,将窗体分配给属性。


推荐阅读