2009-12-02 57 views
0

这是我目前使用来实现对绑定的DataGridView“检查所有”功能是什么:需要更快的DataGridView批量编辑方法

int max = ((DataTable)dataGridRes.DataSource).Rows.Count; 
for (int i = 0; i < max; i++) 
{ 
    if(((DataTable)dataGridRes.DataSource).Rows[i].Field<long>(0) == 0) 
     ((DataTable)dataGridRes.DataSource).Rows[i].SetField(0, 1); 
} 

但是这个代码是无可救药缓慢。在625行DataTable上,我的计算机需要5秒钟才能完成。非常不可接受。

我在做什么错?我可以使用什么更好的方式在DataGridView上进行批量编辑?

回答

1

我找到了一种方法来加速它达到可接受的性能。基本上取消绑定控件,在DataTable上进行更新并重新绑定它。

DataTable dt = (DataTable)dataGridRes.DataSource; 
dataGridRes.DataSource = null; 

for (int i = 0; i < dt.Rows.Count; i++) 
    dt.Rows[i].SetField(0, 1); 

dataGridRes.DataSource = dt; 
+0

对于将自己的答案设置为已接受的答案,我表示歉意。但其他答案都不令人满意,或者实际上帮助加快了所有其他案件的表现。 – 2009-12-09 02:21:13

+1

[不要道歉。](http://meta.stackexchange.com/questions/12513/should-i-not-answer-my-own-questions) – Bobby 2012-02-01 11:16:32

0

第二次尝试。

  1. 您是铸造的方式太多次
  2. 你正在做的if声明表示无所谓

尝试类似:

foreach(DataRow r in ((DataTable)dataGridRes.DataSource).Rows) 
{ 
    r.SetField(0, 1); 
} 
+1

谢谢1月它仍然非常慢。 if语句实际上有助于加速这一过程,因为我最终注意到bootleneck正在进行setfield操作。不过,我找到了一个可以大幅度加速的方法。如果如果解除绑定,则进行批量编辑,然后重新绑定,以加快速度。唯一的问题是,当我重新绑定控件时,复选标记被删除,并被1和0替换。我正在更新我的问题 – 2009-12-02 16:46:47

1

这个博客有你需要什么:DataGridView CheckBox Select All

发布后代码:

public delegate void CheckBoxClickedHandler(bool state); 
public class DataGridViewCheckBoxHeaderCellEventArgs : EventArgs 
{ 
    bool _bChecked; 
    public DataGridViewCheckBoxHeaderCellEventArgs(bool bChecked) 
    { 
     _bChecked = bChecked; 
    } 
    public bool Checked 
    { 
     get { return _bChecked; } 
    } 
} 

class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell 
{ 
    Point checkBoxLocation; 
    Size checkBoxSize; 
    bool _checked = false; 
    Point _cellLocation = new Point(); 
    System.Windows.Forms.VisualStyles.CheckBoxState _cbState = 
     System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal; 

    public event CheckBoxClickedHandler OnCheckBoxClicked; 

    public DatagridViewCheckBoxHeaderCell() 
    { 
    } 

    protected override void Paint(System.Drawing.Graphics graphics, 
     System.Drawing.Rectangle clipBounds, 
     System.Drawing.Rectangle cellBounds, 
     int rowIndex, 
     DataGridViewElementStates dataGridViewElementState, 
     object value, 
     object formattedValue, 
     string errorText, 
     DataGridViewCellStyle cellStyle, 
     DataGridViewAdvancedBorderStyle advancedBorderStyle, 
     DataGridViewPaintParts paintParts) 
    { 
     base.Paint(graphics, clipBounds, cellBounds, rowIndex, 
      dataGridViewElementState, value, 
      formattedValue, errorText, cellStyle, 
      advancedBorderStyle, paintParts); 

     Point p = new Point(); 

     Size s = CheckBoxRenderer.GetGlyphSize(graphics, 
      System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal); 

     p.X = cellBounds.Location.X + 
      (cellBounds.Width/2) - (s.Width/2); 
     p.Y = cellBounds.Location.Y + 
      (cellBounds.Height/2) - (s.Height/2); 

      _cellLocation = cellBounds.Location; 
      checkBoxLocation = p; 
      checkBoxSize = s; 
     if (_checked) 
      _cbState = System.Windows.Forms.VisualStyles. 
      CheckBoxState.CheckedNormal; 
     else 
      _cbState = System.Windows.Forms.VisualStyles. 
      CheckBoxState.UncheckedNormal; 
      CheckBoxRenderer.DrawCheckBox 
      (graphics, checkBoxLocation, _cbState); 
    } 

    protected override void OnMouseClick(DataGridViewCellMouseEventArgs e) 
    { 
     Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y); 
     if (p.X >= checkBoxLocation.X && p.X <= 
      checkBoxLocation.X + checkBoxSize.Width 
      && p.Y >= checkBoxLocation.Y && p.Y <= 
      checkBoxLocation.Y + checkBoxSize.Height) 
     { 
     _checked = !_checked; 
     if (OnCheckBoxClicked != null) 
     { 
      OnCheckBoxClicked(_checked); 
      this.DataGridView.InvalidateCell(this); 
     } 
    } 
    base.OnMouseClick(e); 
    } 
} 

将复选框添加到标题和相应事件代码的代码如下所示。

private void FormatGrid() 
{ 
    DataView dv = new DataView(); 
    dv.Table = _loginDs.Tables[0]; 

    DataGridViewCheckBoxColumn chkbox = new DataGridViewCheckBoxColumn(); 
    DatagridViewCheckBoxHeaderCell chkHeader = new DatagridViewCheckBoxHeaderCell(); 
    chkbox.HeaderCell = chkHeader; 
    chkHeader.OnCheckBoxClicked += new CheckBoxClickedHandler(chkHeader_OnCheckBoxClicked); 
    _chkBoxGrid.Columns.Add(chkbox); 

    DataGridViewTextBoxColumn uname = new DataGridViewTextBoxColumn(); 
    uname.HeaderText = "user"; 
    uname.Name = "username"; 
    uname.DataPropertyName = "username"; 
    _chkBoxGrid.Columns.Add(uname); 

    _chkBoxGrid.DataSource = dv; 
} 

void chkHeader_OnCheckBoxClicked(bool state) 
{ 
    foreach (DataGridViewRow row in _chkBoxGrid.Rows) 
     row.Cells[0].Value = state; 

} 
+0

+1 Roboto。它确实有效。我遇到的唯一问题是,我发现解决方案过度使用时,可以通过代码方式以更简单的方式实现。现在,如果我的电网有几千条记录,我肯定会走这条路。但是,在1000张唱片中,我不觉得有必要这样做。我仍然保存在我的代码片段中。谢谢。 – 2009-12-09 02:24:24

0

当一个DataTable编辑多个行或列,请拨打BeginLoadData 1日,然后调用EndLoadData时,即可大功告成。

+0

-1。对不起hjb417。但是这显然与BeginLoadData或EndLoadData无关。 – 2009-12-09 02:25:40