解决思路梳理:
一.采用委托事件解决。
设置某个功能码预设值,将预设值放进字典映射表中后,触发事件,调用委托方法,调用重新加载各组功能码函数,出现问题:操作无效,原因是它导致对 SetCurrentCellAddressCore 函数的可重入调用。原因在于,设定预设值操作cell单元格,然后又想同时刷新datagridview,出现冲突。不能在datagridView_CellEndEdit事件内重新绑定,可以用invoke异步调用重新绑定
二.异步调用方法
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。
正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。
而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (DialogResult.OK == MessageBox.Show("是否要修改", "", MessageBoxButtons.OKCancel))
{
Users user = new Users();
user.UserName = this.dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
user.Password = this.dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
string sql = "update [用户表$] set 用户名='" + user.UserName + "',密码='" + user.Password + "' where 用户名='" + user.UserName + "'";
int count = OledbHelper.ExecuteNonquery(sql);
if (count == 1)
{
MessageBox.Show("修改成功");
//修改成功后,创建新的线程
Thread thread = new Thread(DoWork);
thread.Start();
}
}
}
public delegate void MyInvoke();
public void DoWork()
{
MyInvoke mi = new MyInvoke(LoadData);
this.BeginInvoke(mi,new Object[]{true});
}
public void LoadData()
{
//重新绑定数据源
this.dataGridView1.DataSource = dataSetResult.Tables[0];
}
不再报错,但是预设值依旧为空。原因在于 Datagridview里面一些设置,比如说列名是不是和你的m_table 里面一致。发现预设值列在设计器中未绑定数据DataPropertyName,添加预设值之后,问题解决。
举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个TextBox.. (在vs创建工程,拖一个button控件,一个texbox控件即可运行)
using System.Threading;
namespace test
{
public partial class Form1 : Form
{
public delegate void MyInvoke(string str1,string str2);
public Form1()
{
InitializeComponent();
}
public void DoWork()
{
MyInvoke mi = new MyInvoke(UpdateForm);
this.BeginInvoke(mi, new Object[] {"我是文本框","haha"});
}
public void UpdateForm(string param1,string parm2)
{
this.textBox1.Text = param1+parm2;
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
}
}
}