"Object reference not set..." 将控件添加到另一个窗体时出现异常

"Object reference not set..." exception when adding control to another form

我想在用户单击当前位于面板 (UserControl1).单击此按钮时,UserControl2 应将 UserControl1 替换为面板的内容。

我已经尝试弄清楚如何使用事件在 UserControl1MainForm 之间进行通信,但我不知道从哪里开始,因为我找不到示例这很容易适应我的特定情况(向面板添加控件)。

THIS 问题很相似,但不太适合我正在尝试做的事情(或者至少我只是不知道如何使它适应我正在尝试做的事情)

我试过这个方法,没有出现错误,但我的按钮没有任何作用:

主窗体:

    private void SubscribeToEvent(MyUserControl1 Button_Click)
    {
        MyUserControl1 CurrentClass = new MyUserControl1();
        CurrentClass.Button.Click += new EventHandler(this.ButtonClickHandler);
    }

    private void ButtonClickHandler(object sender, EventArgs e)
    {
        MyUserControl2 MainPanelControls = new MyUserControl2();
        MainPanel.SuspendLayout();
        MainPanel.Controls.Clear();
        MainPanel.Controls.Add(MainPanelControls);
        MainPanel.ResumeLayout();
    }

UserControl1:

    public void Button_Click(object sender, EventArgs e)
    {
        //... Not sure what I'm missing here
    }

我也尝试过这种方法,这次尝试实现类似于我问题顶部附近的 link 中描述的方法。我知道这些显然是错误的(否则我就不需要问这个问题了),但我对这个问题的了解不足,无法自行解决:

UserControl1:

    public MyUserControl1()
    {
        InitializeComponent();
    }

    private MainForm mainForm = null;
    public MyUserControl1(Form callingForm)
    {
        mainForm = callingForm as MainForm;
        InitializeComponent();
    }

//...

    private void Button_Click(object sender, EventArgs e)
    {
        MyUserControl2 MainPanelControls = new MyUserControl2();
        mainForm.MainPanel.SuspendLayout();
        mainForm.MainPanel.Controls.Clear();
        mainForm.MainPanel.Controls.Add(MainPanelControls);
        mainForm.MainPanel.ResumeLayout();
    }

现在,当我单击 Button 时,我在 mainForm.MainPanel.SuspendLayout(); 处(或超过该点的任何地方)收到 "Object reference not set to an instance of an object" 错误。

我也试过修改 Joh 的答案,但最终还是出现了同样的 Null Reference Exception,这次是在我 ButtonClickedToMainForm(this, e);Button_Click 事件上 我不确定是否需要创建ButtonClickedToMainForm 的一个实例,或者如何正确地做到这一点(如果不是别的东西,那就是)。

我感觉我可能只是将其中一些代码放在了错误的位置,所以我希望更有经验的人可以帮助我解决这个问题。

更新

这是我尝试实现 Joh 的回答,对此太陌生了,我不太确定我在哪里搞砸了:

主窗体:

namespace MyProject
{
public delegate void ButtonClickToMainForm(object sender, EventArgs e);

public partial class MainForm : Form
{

    public MainForm()
    {
        InitializeComponent();
        UserControl1 userControl1 = new UserControl1();
        userControl1.Button1Clicked += userControl1_Button1Clicked;
    }

    private void userControl1_Button1Clicked(object sender, EventArgs e)
    {
        try
        {
            UserControl2 MainPanelControls = new UserControl2();
            MainPanel.SuspendLayout();
            MainPanel.Controls.Clear();
            MainPanel.Controls.Add(MainPanelControls);
            MainPanel.ResumeLayout();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
  }
}

UserControl1:

public partial class UserControl1: UserControl
{
    public event ButtonClickToMainForm Button1Clicked;

    public UserControl1()
    {
        InitializeComponent();
    }

    private void OnButton1Clicked(object sender, EventArgs e)
    {
        Button1Clicked?.Invoke(this, e);
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        Button1Clicked(this, e);  //"Object reference not set to an instance of an object."
    }
}

我确定我在 UserControl1 上遗漏了一些简单的东西,我只是不确定是什么。

这是一个简单的委托示例 event.When 您在所有用户控件中实现它应该可以解决您的问题。

用户控件:

//Create a delegate
    public delegate void ButtonClickToMainForm(object sender, EventArgs e);

    public partial class UserControl1 : UserControl
    {
        //Your own event based on created delegate
        public event ButtonClickToMainForm ButtonClickedToMainForm;

        public UserControl1()
        {
            InitializeComponent();
        }

       //This method will invoke your event
        private void OnButtonClickedToMainForm(object sender, EventArgs e)
        {
            ButtonClickedToMainForm?.Invoke(this, e);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //On button1_Click this will fire the event on mainform
            OnButtonClickedToMainForm(this, e);
        }

和主窗体:

 public Form1()
        {
            InitializeComponent();
            //Subscribe to event from your usercontrol
            userControl11.ButtonClickedToMainForm += UserControl11_ButtonClickedToMainForm;
        }

        //Button on userControl1 has been clicked
        private void UserControl11_ButtonClickedToMainForm(object sender, EventArgs e)
        {
            //do your things here...
        }

希望对您有所帮助。