我现在的处境是:查看图像
有5个用户控件堆叠在空面板中
我有一个垂直菜单,其中有几个按钮,当我单击一个按钮时,我使用:BringToFront()
来显示它们
private void Button1_Click(object sender, EventArgs e)
{
tabRandom1.BringToFront();
}
每个usercontrol
都包含datagridview
和其他elements
,它们必须加载来自数据库的数据,但我希望如果单击button1
,只加载usercontrol1
的元素
当我尝试时:
private async void UserControl1_Load(object sender, EventArgs e)
{
this.DataGridView1.DataSource = await GetDataAsync();
}
我得到一个异常@er shoaib:
there is already an open DataReader associated with tis connection which must be closed first.
我正在寻找加载活动用户控件元素的最佳方式
您得到的错误清楚地表明您已经打开了DataReader
。
一个连接中不能有多个打开的DataReader
。
为了使您与数据库通信的代码更加稳定,请使用using
编写代码,它会自动处理这样的对象:
using(SqlConnection con = new SqlConnection("..."))
{
con.Open();
using(SqlCommand cmd = new SqlCommand("...", con))
{
using(SqlDataReader dr = cmd.ExecuteReader())
{
while(dr.Read())
// Do the things
}
}
// Do not need close since connection will be disposed
}
或者,如果你为全班打开了一个连接(就像我想你在那里做的那样),不要把SqlConnection con = new Sql....
包装在using
里面,而是其他人做的一切,你不会有任何问题,除了不要忘记做connection.Close()
。
我总是对sql连接中的每个组件使用using
,这不会影响我的性能。
当你以这种方式重新组织代码时,你就会摆脱这个问题,但有一个建议是,当有人打开表单时不要加载数据,因为你将加载它5次,用户可能只使用一种更好的创建方法,如在UC中创建RefreshData()
,在执行yourUserControl.BringToFront();
之前,你也要执行yourUserControl.RefreshData()
,这样你只会在需要时加载它,而且你总是会有新的数据,此外,如果需要,你可以在任何地方轻松地刷新数据。