关于“未将对象引用到设置对象的实例”错误下面这段代码是参照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";
}
} }
但是,每次执行都会提示这个错误,我实验从工具箱中拖出一个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";
}
} }
代码是参考
http://blog.csdn.net/kissyougoodby/archive/2007/09/12/1782550.aspx
{
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段是空白的,这个错误被忽略了,所以不显示。似乎是没有错误。我后来写的代码段中加入了对异常的处理,故而困惑了良久.......,哈哈,解决了。准备散分,分不多意思一下,进者有分咯