关于“未将对象引用到设置对象的实例”错误下面这段代码是参照csdn上的一篇关于将datagridview里显示自定义控件的方法写的,功能是将返回表格的第4列显示为一个combox控件。
但是,每次执行都会提示这个错误,我实验从工具箱中拖出一个combox控件命名为cmb而不是使用ComboxBox cmb = new ComboxBox();的方法,这样combox就能狗正确显示了,遗憾的是位置不是正好和单元格重叠,而是在距离单元格上面。
调试也看不出那里的问题。
出错代码如下:
    public partial class ADD : Form
    {
        private System.Windows.Forms.ComboBox cmb = new System.Windows.Forms.ComboBox();
        public string _conn = System.Configuration.ConfigurationManager.AppSettings["connstr"];
        public ADD()
        {
            InitializeComponent();
        }            private void Serach_Click(object sender, EventArgs e)
        {
            SqlConnection conn = new SqlConnection(_conn);
            SqlCommand cmd = new SqlCommand("NormalSelect",conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add("@MC",SqlDbType.NVarChar);
            cmd.Parameters["@MC"].Value = textBox1.Text;
            SqlDataAdapter sa = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            sa.Fill(dt);
            this.bindingSource1.DataSource = dt;
            this.dataGridView1.DataSource = bindingSource1;
        }        private void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView1.CurrentCell.ColumnIndex == 3)
                {
                    Rectangle rect = this.dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex,true);
                    string cellstr = this.dataGridView1.CurrentCell.Value.ToString();
                    if (cellstr == "Overdue") cmb.Text = "过期";
                    else if (cellstr == "Accept") cmb.Text = "生效";
                    cmb.Left = rect.Left;
                    cmb.Top = rect.Top;
                    cmb.Width = rect.Width;
                    cmb.Height = rect.Height;
                    cmb.Visible = true;
                }
                else
                {
                    cmb.Visible = false;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            
            }        }
        private void cmbinit()
        {
            DataTable dataT = new DataTable();
            DataRow DataR;
            dataT.Columns.Add("flag");
            dataT.Columns.Add("display");
            DataR = dataT.NewRow();
            DataR[0] = "Overdue";
            DataR[1] = "过期";
            dataT.Rows.Add(DataR);
            DataR = dataT.NewRow();
            DataR[0] = "Accept";
            DataR[1] = "生效";
            dataT.Rows.Add(DataR);            this.cmb.ValueMember = "flag";
            this.cmb.DisplayMember = "display";
            this.cmb.DataSource = dataT;
            this.cmb.DropDownStyle = ComboBoxStyle.DropDownList;
            this.cmb.Location = new System.Drawing.Point(130, 117);        }        private void ADD_Load(object sender, EventArgs e)
        {
            cmbinit();
            this.cmb.Visible = false;
            this.cmb.SelectedIndexChanged += new EventHandler(cmb_SelectedIndexChanged);        }
        private void cmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (((ComboBox)sender).Text == "过期")
            {
                this.dataGridView1.CurrentCell.Value = "过期";
                this.dataGridView1.CurrentCell.Tag = "Overdue";
            }
            else
            {
                this.dataGridView1.CurrentCell.Value = "生效";
                this.dataGridView1.CurrentCell.Tag = "Accept";
            }
        }    }

解决方案 »

  1.   

    我怀疑是combox控件出了问题,但是实在找不出问题在那里,反正每次都显示“未将对象引用到设置对象的实例”
    代码是参考
    http://blog.csdn.net/kissyougoodby/archive/2007/09/12/1782550.aspx
      

  2.   

    经过我昨天自己慢慢调试,终于明白问题出到那里了。在参考的KissyougoodBye的blog里,关于CurrentCellChanged的事件是这样写的:private void dgv_User_CurrentCellChanged(object sender, EventArgs e)
    {
        try
        {
            if (this.dgv_User.CurrentCell.ColumnIndex == 2)
            {
                Rectangle rect = dgv_User.GetCellDisplayRectangle(dgv_User.CurrentCell.ColumnIndex, dgv_User.CurrentCell.RowIndex, false);
                string sexValue = dgv_User.CurrentCell.Value.ToString();
                if (sexValue == "1")
                {
                    cmb_Temp.Text = "男";
                }
                else
                {
                    cmb_Temp.Text = "女";
                }
                cmb_Temp.Left = rect.Left;
                cmb_Temp.Top = rect.Top;
                cmb_Temp.Width = rect.Width;
                cmb_Temp.Height = rect.Height;
                cmb_Temp.Visible = true;
            }
            else
            {
                cmb_Temp.Visible = false;
            }
        }
        catch
        {
        }
    }
    我也是模仿了这样来写,唯一不同的是catch段,问题的关键其实是出在
     Rectangle rect = dgv_User.GetCellDisplayRectangle(dgv_User.CurrentCell.ColumnIndex, dgv_User.CurrentCell.RowIndex, false);
    这一句上。
    我在事件的起始处设置了一个断点,发现CurrentCellChanged事件并非是用户改变当前单元格才会发生的,在DataGridview控件绑定数据源完成开始填充数据的第一行第一列之前,就会引发一个CurrentCellChanged事件,而这个时候,CurrentCell还没有被显示出来,所以,就会抛出一个“未将对象引用到设置对象的实例”错误,而在KissyougoodBye兄提供的源码中的catch段是空白的,这个错误被忽略了,所以不显示。似乎是没有错误。我后来写的代码段中加入了对异常的处理,故而困惑了良久.......,哈哈,解决了。准备散分,分不多意思一下,进者有分咯