NullReferenceException未被处理 - 什么是null?

3

我正在尝试通过点击按钮(btnsearch_Click)访问主表单中的事件,每次我点击它,它都会显示“对象引用未设置为对象实例”。

以下是我的代码:

用户控件

namespace Purchase_Order
{
    public partial class Search : UserControl
    {
        public event EventHandler btnSearchClicked;

        public Search()
        {
            InitializeComponent();
        }
        private void btnsearch_Click(object sender, EventArgs e)
        {

           btnSearchClicked(sender, e);
        }
   }
}

主要表格

namespace Purchase_Order
{
    public partial class formMain : Form
    {

        public formMain()
        {
            InitializeComponent();            
        }




 private void formMain_Load(object sender, EventArgs e)
        {

Search searchbox = new Search();
searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}


 void SearchClicked(object sender, EventArgs e)
        {
            MySqlConnection con = new MySqlConnection(serverstring);

            try
            {

                string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, @search)";

                MySqlCommand cmd = new MySqlCommand(query, con);
                MySqlDataAdapter da = new MySqlDataAdapter(cmd);

                Search content = new Search();
                cmd.Parameters.AddWithValue("@search", content.btnsearch.Text);

                DataTable dt = new DataTable();
                da.Fill(dt);


                classification control = new classification();
                control.dataGridView1.DataSource = dt;
                control.dataGridView1.DataMember = dt.TableName;

                panelMain.Controls.Clear();
                panelMain.Controls.Add(control);
                MessageBox.Show("OK");

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }    
        }

1
serverstring 变量在哪里初始化了? - Ant P
2
你能使用Visual Studio调试器看到哪一行代码抛出了错误吗? - Prabhu Murthy
@AntP 对不起,我忘记复制服务器字符串代码了,这是它的代码:string serverstring = "user id = root; password=; server=localhost; database=purchase_order; connection timeout=3;"; - Harvey
@CodeIgniter,它在这一行上 -> btnSearchClicked(sender, e); - Harvey
@AntP,我不明白他的意思,他说我没有注册该事件?这是什么意思? - Harvey
显示剩余3条评论
4个回答

4

您正在SearchClicked方法中创建一个新的用户控件实例,但未对其注册事件。

Search content = new Search();

最好在触发事件之前检查是否有任何控件注册了您的事件,例如:

private void btnsearch_Click(object sender, EventArgs e)
{
 if(btnSearchClicked != null)
       btnSearchClicked(sender, e);
}

我已经在这一行中注册了它 -> 搜索内容 = new Search(); 这是什么意思? - Harvey
@user2083771,您没有使用此实例注册事件“btnSearchClicked”。您可以像这样注册事件:“content.btnSearchClicked += new EventHandler(SearchClicked);”或在窗体加载时使用您之前创建的用户控件。将其定义为类级别,然后您可以在两种方法中使用它。 - Habib
еҘҪзҡ„пјҢжүҖд»ҘжҲ‘еңЁжҲ‘зҡ„дё»иЎЁеҚ•SearchClickedеҮҪж•°дёӯж·»еҠ дәҶд»Јз ҒSearch content = new Search(); content.btnSearchClicked += new EventHandler(SearchClicked);пјҢдҪҶе®ғжҳҫзӨәзӣёеҗҢзҡ„й”ҷиҜҜгҖӮ - Harvey
@user2083771,对于Search,请使用类级别对象,您正在事件内创建实例。 - Habib
先生,同样的错误。这是我的代码,在formMain类下:Search content = new Search();void SearchClicked(object sender, EventArgs e) { content.btnSearchClicked += new EventHandler(SearchClicked); } - Harvey
@user2083771,我已经发布了一个更详细的解释,作为一个单独的答案 - 希望这能帮助你更好地理解问题。 - Ant P

3
这意味着你没有所需类型的实例。 public event EventHandler btnSearchClicked;只是你想要使用的“真实”对象的引用。
这就像你试图打开一扇房子的门,但你只有蓝图。这并不是真正可能的(至少在我们的宇宙中)。你首先需要建造房子,然后再尝试进入它。类似于你的问题情况。
你需要阅读一些关于C#的教程。
编辑:
null的问题在于你的引用指向的东西不存在。如果你什么也没创建,那么就没有任何东西可以引用...
因为你正在尝试使用不存在的东西(即null),所以你会得到一个异常。

问题是“null是什么”,而不是“null意味着什么?” - Ant P
2
@AntP 这个问题有点含糊不清,我认为他不应该被扣分。 - Theodoros Chatzigiannakis

1
我会尽力扩展一下Habib的答案(我本来想把这个作为评论发出来,但是有点长),首先你要创建一个Search实例,并在formMain_Load中注册事件。
private void formMain_Load(object sender, EventArgs e)
{
    Search searchbox = new Search();
    searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}

这些都很好。然而,在SearchClicked中,你会创建一个Search实例,如下所示:
Search content = new Search();

这是一个与您在formMain_Load中创建的对象分开的对象,您从未将事件注册到此对象。看起来您想要做的是在SearchClicked方法中共享formMain_Load中的Search实例。为此,请在代码后台中创建一个属性:
public partial class formMain : Form
{
    private Search _searchbox;
    ...
}

然后,在 formMain_Load 中:
private void formMain_Load(object sender, EventArgs e)
{
    _searchbox = new Search();
    _searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}

现在,您可以通过更改以下内容,重复使用已注册在SearchClicked中的事件对象:
Search content = new Search();

To this:

Search content = _searchbox;

你应该发现异常已经消失了。希望这能提供一些更深入的见解,并帮助你理解错误的原因以及如何规避它。


我已经尝试过了,它可以正常工作。对不起我的问题有点无聊,但还是谢谢你的帮助。 - Harvey

0

在formMain_Load方法中共享Search实例,以便在SearchClicked方法中使用

主窗体

 public partial class formMain : Form
    {
        private Search _searchbox;
        ...

private void formMain_Load(object sender, EventArgs e)
{
    _searchbox = new Search();
    _searchbox.btnSearchClicked += new EventHandler(SearchClicked);
}

void SearchClicked(object sender, EventArgs e)
        {


     Search content = _searchbox;

MySqlConnection con = new MySqlConnection(serverstring);

            try
            {

                string query = "SELECT * FROM tblclassification WHERE INSTR(class_name, @search)";

                MySqlCommand cmd = new MySqlCommand(query, con);
                MySqlDataAdapter da = new MySqlDataAdapter(cmd);


                cmd.Parameters.AddWithValue("@search", content.btnsearch.Text);

                DataTable dt = new DataTable();
                da.Fill(dt);


                classification control = new classification();
                control.dataGridView1.DataSource = dt;
                control.dataGridView1.DataMember = dt.TableName;

                panelMain.Controls.Clear();
                panelMain.Controls.Add(control);
                MessageBox.Show("OK");

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (con.State == ConnectionState.Open)
                {
                    con.Close();
                }
            }    
            }
        }

用户控件

public partial class Search : UserControl
    {
        public event EventHandler btnSearchClicked;

        public Search()
        {
            InitializeComponent();
        }
        private void btnsearch_Click(object sender, EventArgs e)
        {

           btnSearchClicked(sender, e);
        }
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接