c# - "Object reference not set..."向另一个窗体添加控件时出现异常

标签 c# events controls panel subscribe

我想在用户单击当前位于面板 (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();
    }

用户控件1:

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

我也尝试过这种方法,这次尝试实现类似于我问题顶部附近链接中描述的方法的东西。我知道这些显然是错误的(否则我不需要问这个问题),但我对这个问题没有足够的知识来自己弄清楚:

用户控件1:

    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);
        }
    }
  }
}

用户控件1:

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 上遗漏的一些简单的东西,我只是不确定是什么。

最佳答案

这是委托(delegate)事件的一个简单示例。当您在所有用户控件中实现它时,它应该可以解决您的问题。

用户控件:

//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...
        }

希望这对您有所帮助。

关于c# - "Object reference not set..."向另一个窗体添加控件时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35418308/

相关文章:

c# - 如果 C# 规范将它们称为简单类型,为什么 Type 类有一个名为 IsPrimitive() 的方法?

javascript - HTML、Javascript 中的自定义事件

.net - 自定义Windows窗体滚动条

asp.net - ASP.NET 中的格式化控件

c# - WinForms/C# : Adding items to Combox and controlling the Item value (numeric)

c# - 将收件人电子邮件地址添加到电子邮件正文

c# - 使用 protobuf 为 c# 反序列化 "long"字符串对我来说不能正常工作

c# - 双击定时器事件

javascript - 重置 document.ready ($.getScript)

java - 鼠标释放时对 JTable 进行排序