向用户控件添加面板时出错:对象引用未设置为对象的实例

本文关键字:设置 对象引用 对象 实例 出错 控件 用户 添加 | 更新日期: 2023-09-27 18:19:20

我有一个问题。我正试图访问用户控件中的面板。当我在一个表单中访问它时,它就工作了。之前我这样做过。

我从用户控件访问表单中的面板,它工作了。下面是我使用的代码:

Form1 form = Application.OpenForms.OfType<Form1>().FirstOrDefault();
            form.Panel1.Controls.Clear();
            ManageControl user = new ManageControl();
            form.Panel1.Controls.Add(user);

但是当我尝试在用户控件中使用相同的概念时,它不起作用。

抛出null错误:Object reference not set to an instance of an object.

代码如下:

//this is in ManageControl.cs
public Panel Panel2
        {
            get { return panelmanage; }
        } 

//这是另一个userControl。试图访问panelImage

 ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
            form.Panel2.Controls.Clear();//it throws the error here
            ReportControl user = new ReportControl();
            form.Panel2.Controls.Add(user);

我做错了什么,因为我使用相同的概念?

编辑:

这是我的ManageControl.cs

 public partial class ManageControl : UserControl
    {
        public ManageControl()
        {
            InitializeComponent();
            
        }
        public Panel Panel2
        {
            get { return panelmanage; }
           
        }

这是我在BookingListControl

中访问它的方法
public partial class BookingListControl : UserControl
    {
        ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
        public BookingListControl()
        {
            InitializeComponent();
        }
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ManageControl form = Application.OpenForms.OfType<ManageControl>().FirstOrDefault();
         
            ReportControl user = new ReportControl();
            form.Panel2.Controls.Add(user);
        }

向用户控件添加面板时出错:对象引用未设置为对象的实例

ManageControlUserControl而不是Form。因此,当您寻找类型ManageControl的开放形式时,您将一无所获(这里没有什么奇怪的)。然后,我们调用FirstOrDefault,它返回null(因为在空集合中没有匹配的元素),并且您的下一行爆炸。

这种方法从一开始就注定要失败,因为即使你有一大堆表单相互覆盖,可以使它工作(坏主意),一旦你有两个 ManageControl对象,并且需要访问第二个,它就会崩溃。

相反,首先问自己,"为什么我的UserControl对象需要相互访问?"这是一个重要的问题,因为通常UserControl是独立的。它们可能有将数据返回给父节点的方法,但仅此而已。它们当然不会与其他UserControls交互。

如果你决定你真的需要这个依赖,那么我将父Form对象传递给两个UserControl,并在Form上有一个公共属性,允许他们看到另一个UserControl。从这里您可以正常访问它(不需要任何OpenForms废话)。老实说,这是一个巨大的代码气味,听起来好像整个设计应该看看你有哪些依赖可以被删除。

要做到这一点,您需要在表单上公开ManageControl:
public class ParentForm : Form
{
    public ManageControl Manager { get { return manageControlInstance; } }
    ...
}

然后在子控件中访问它。最简单的方法是通过Parent属性,但您也可以将其传递给构造函数或Init函数。

public class ChildControl : UserControl
{
     private void SomeFunction()
     {
         (Parent as ParentForm).Manager.Panel2.Controls.Add(new ReportControl());
     }
}

代码非常丑陋,我不建议这样做(如果你把ChildControl放到ParentForm以外的任何东西中也不安全)。也就是说,工作

假设基于访问"Panel2"属性而发生NullReferenceException,则您的问题是"panelmanage"为空。查找并填充"表单"的代码。Panel2"在窗体或控件构造函数?如果是这样,请尝试重构它,使其在ManageControl完全初始化之后运行——也许可以将其放入一个Loaded事件中。