将控件添加到另一个表单时,“对象引用未设置...”异常

时间:2016-02-15 20:18:39

标签: c# events controls panel subscribe

当用户单击当前位于面板中的UserControl上的按钮时,我想将UserControl(UserControl2)添加到另一个表单(MainForm)上的面板中{{1 }})。单击此按钮时,UserControl1应将UserControl2替换为面板内容。

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

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

我尝试过这种方法,没有错误,但我的按钮没有做任何事情:

的MainForm:

MainForm

的UserControl1:

    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
    }

现在当我点击 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(或者过去的任何地方)发生了"Object reference not set to an instance of an object"错误。

我也尝试修改了Joh的答案,但最终得到了相同的Null Reference Exception,这次是mainForm.MainPanel.SuspendLayout(); Button_Click事件我不确定是否需要创建实例是ButtonClickedToMainForm(this, e);,或者如何正确地做到这一点(如果它不是别的,那就是)。

我有一种感觉,我可能只是把这些代码放在了错误的地方,所以我希望有经验的人可以帮助我解决这个问题。

更新

这是我尝试实施Joh的答案,对此我是新手,我不太确定我搞砸了哪里:

的MainForm:

ButtonClickedToMainForm

的UserControl1:

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

我确信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." } } 上我缺少一些简单的东西,我只是不确定是什么。

1 个答案:

答案 0 :(得分:1)

以下是委托事件的简单示例。当您在所有用户控件中实现它时,它应该适用于您的问题。

用户控件:

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

和mainForm:

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

希望这有帮助。