多线程+datagridview的问题

beifengchuiqi 2012-05-07 03:30:26
看代码

测试代码1:在datagridview里输出一个 1*10的数组,值为1~10.

private void fuc()
{
char[] tmpValue = "1,2,3,4,5,6,7,8,9,10".ToCharArray();
string[] strs = (new string(tmpValue)).Split(',');

DataTable dt = new DataTable("Data");
DataRow dr;

dr = dt.NewRow();
for (int j = 0; j < strs.Length; j++)
{
dt.Columns.Add(new DataColumn(((char)('A' + j)).ToString(), typeof(double)));
dr[j] = strs[j];
}
dt.Rows.Add(dr);

dataGridView1.DataSource = dt;
}


代码2:作用是 单击button2按钮,进行显示fuc操作。这个没有问题。(多次操作也没有问题)

private void button2_Click(object sender, EventArgs e)
{
fuc();
}


代码3:问题来了,当我用多线程调用fuc()函数的时候就会出现:第一次操作没有问题,但是点击第二次(包括第三第四……次)时就会提示错误。(错误已经在下面贴出)。

private void button1_Click(object sender, EventArgs e)
{
//MessageBox.Show("xx");//此时如果我将这段代码不注销,这个错误只是偶尔会出现。
Thread thread = new Thread(fuc);
thread.Start();
}




错误提示:

有关调用实时(JIT)调试而不是此对话框的详细信息,
请参见此消息的结尾。

************** 异常文本 **************
System.NullReferenceException: 未将对象引用设置到对象的实例。
在 System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
在 System.Windows.Forms.DataGridViewTextBoxCell.Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, Object value, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
在 System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
在 System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
在 System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)
在 System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
在 System.Windows.Forms.Control.WmPaint(Message& m)
在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.DataGridView.WndProc(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)





求解!
...全文
411 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
堆栈信息看似和我一样,应该还会出现一个大红叉号。 一段痛苦的经历~~ 解决方法如下:

public class DataGridViewPlus : DataGridView { 
	{
		try { 
			base.OnPaint( e ); 
		} 
		catch { 
			Invalidate(); 
		} 
	} 
}
参考: (1) http://wenku.baidu.com/view/a3a7ed0d79563c1ec5da7126.html (2) http://social.msdn.microsoft.com/Forums/windows/en-US/fdd94896-80e9-4e91-9ed5-0348bf2633a9/datagridview-red-x?forum=winforms
tianlongk 2013-04-30
  • 打赏
  • 举报
回复
引用 5 楼 icefirephenix 的回复:
代码不可以标红么,擦
可以的,不过是点击源码那个按钮后可以看到的
花痴 2012-05-07
  • 打赏
  • 举报
回复
代码不可以标红么,擦
花痴 2012-05-07
  • 打赏
  • 举报
回复

private void fuc()
{
char[] tmpValue = "1,2,3,4,5,6,7,8,9,10".ToCharArray();
string[] strs = (new string(tmpValue)).Split(',');

DataTable dt = new DataTable("Data");
DataRow dr;

dr = dt.NewRow();
for (int j = 0; j < strs.Length; j++)
{
dt.Columns.Add(new DataColumn(((char)('A' + j)).ToString(), typeof(double)));
dr[j] = strs[j];
}
dt.Rows.Add(dr);

lock(dt)
{
this.BeginInvoke(new Action(()=>dataGridView1.DataSource = dt));
}

}

注:红色部分的Action貌似需要3.x的framework才有的
NewUser2008 2012-05-07
  • 打赏
  • 举报
回复
把DataGridView显示模式改为虚模式,用Invoke刷新DataGridView





private void RefUI<T>(List<T> list)
{
if (InvokeRequired)
{
BeginInvoke(new Action<List<T>>(RefUI),list);
}
else
{
dataContainer.RowCount = list.Count;

dataContainer.Refresh();

}
}
//虚模式数据绑定事件
private void dataContainer_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
if (list != null && list.Count > 0 && list.Count > e.RowIndex)
{
T t = list[e.RowIndex];
//绑定
}
}
zhujiawei7 2012-05-07
  • 打赏
  • 举报
回复
需要用委托、Invoke来解决,你可以再网上搜下“跨线程调用控件”。
zhujiawei7 2012-05-07
  • 打赏
  • 举报
回复
这是因为你从线程去操作datagridview的原因

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧