Нужен более быстрый метод массового редактирования DataGridView - PullRequest
0 голосов
/ 02 декабря 2009

Это то, что я сейчас использую для реализации функции «Проверить все» в привязанном 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?

Ответы [ 4 ]

1 голос
/ 09 декабря 2009

Я нашел способ ускорить его до приемлемой производительности. По сути, отмените привязку элемента управления, выполните обновление в 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;
1 голос
/ 02 декабря 2009

В этом блоге есть все, что вам нужно: DataGridView CheckBox Выбрать все

Код выложен для потомков:

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 голосов
/ 02 декабря 2009

При редактировании нескольких строк или столбцов в DataTable, вызовите BeginLoadData 1-й и затем вызовите EndLoadData , когда вы закончите.

0 голосов
/ 02 декабря 2009

Вторая попытка.

  1. Вы используете слишком много раз
  2. Вы делаете if заявление, которое не имеет значения

попробуйте что-то вроде:

foreach(DataRow r in ((DataTable)dataGridRes.DataSource).Rows)
{
    r.SetField(0, 1);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...