2012-01-03 484 views
2

我一直在用CellFormatting事件挣扎,它太慢了。C#中的CellFormatting事件真的很慢

我有一个DataGridView是这样的:

enter image description here

我已经写了,当你点击复选框选中的报头火的功能,它使所有的复选框,在列检查.. ..

private void checkboxHeader_CheckedChanged(object sender, EventArgs e) 
    { 
     for (int i = 0; i < dataGridView1.RowCount; i++) 
     { 
      dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked; 
     } 
     //dataGridView1.EndEdit(); 
    } 

而这个功能在工作时,我有一些像10排它完美的作品,但是当我有300行的东西,我应该有...有一个类似9秒延迟使所有复选框检查,我发现这是由于CellFormating事件。

我CellFormating事件的代码是:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
     { 

      DataGridViewCellStyle _myStyle = new DataGridViewCellStyle(); 
      int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value); 
      if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1) 
      { 
       //e.CellStyle = _myStyle; 
       _myStyle.Font = gdv_row[index].font; 
       _myStyle.BackColor = gdv_row[index].backgroundcolor_color; 
       _myStyle.ForeColor = gdv_row[index].foregroundcolor_color; 
       dataGridView1.Rows[e.RowIndex].Cells[1].Style = _myStyle; 
      } 
     } 

,我已经使用DoubleBuffering for DataGridView。现在我不知道我该如何处理这个C​​ellFormatting事件...

回答

3

你已经试过SuspendLayout()ResumeLayout()

这会暂时中止控件的布局逻辑,以便在填充它时不会重新绘制网格。

如果使用DoubleBuffering,网格仍会重新绘制自己,但仍然很慢。但是,如果您在填充网格时完全不重绘,则应该给出戏剧性的动作。然后

你的第一个函数可能是这样的:

private void checkboxHeader_CheckedChanged(object sender, EventArgs e) 
    { 
     dataGridView1.SuspendLayout(); 

     for (int i = 0; i < dataGridView1.RowCount; i++) 
     { 
      dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked; 
     } 

     dataGridView1.ResumeLayout(); 
    } 

[编辑1]

添加了代码示例。

[编辑2] 为了最小化行的必要的附图中,而不是对每个行创建新DataGridViewCellStyle对象,尝试直接设置现有的样式的属性:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
    { 
     int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value); 
     if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1) 
     { 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.Font = gdv_row[index].font; 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.BackColor = gdv_row[index].backgroundcolor_color; 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.ForeColor = gdv_row[index].foregroundcolor_color; 
     } 
    } 

最后,寻找一些解决方案,我发现这个MSDN文章文档: Best Practices for Scaling the Windows Forms DataGridView Control

[编辑3](响应低于伊赫桑的评论)

这是因为“a”是即时显示在网格中的值,而原始行执行了一些重要工作: *执行搜索所需的值,包括所有子控件 *创建一个数组与发现结果 *使从对象强制转换为复选框 *它所有的这每每一条线在你的网格

因此很显然,这变得更加耗时,你有更多的项目在您的DataGridView 。

如果我理解你的代码正确它应该帮助你改变方法到这一点:

CheckBox headerBox = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]); 
    for (int i = 0; i < dataGridView1.RowCount; i++) 
    { 
    dataGridView1[0, i].Value = headerBox.Checked; 
    } 

这样做,你只能执行一次搜索。

+0

SuspendLayout是要去帮助,当你添加新的你表单上的对象。根据MSDN的说法,SuspendLayout'临时挂起控件的布局逻辑.' – 2012-01-03 12:25:56

+0

感谢您的回复,请您给出更详细的答案,或者因为我不知道如何使用此功能以及在哪里? – Ehsan 2012-01-03 12:33:41

+0

其实我做了你所说的,但即使我看到更多的延迟,仍然有这种延迟!但我应该怎么做?你认为也许dataGridView1 [0,i]有一些错误,并使延迟?:( – Ehsan 2012-01-03 13:44:02