From: Matthijs de Z on
Hi,

I would like to be able to multi select rows in a datagridview, just
by clicking a cell in the rows I need.
The code below, does work. But it looks like it might not be the most
efficient way to do this. When I run the program and select rows, the
datagrid does not really instantly change, but you can see it
changing. It's kind of slow, while my machine is not slow at all. Is
there a more efficient way to do this? Can I let the datagrid stop
from updating, till the foreach loop is done and then start updating
again? If so, how can I stop the datagrid from updating / refreshing?
Kind regards,


Matthijs


private List<int> RowIndexTracker = new List<int>();

private void dataGridView1_CellMouseClick(object sender,
DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
if (RowIndexTracker.Contains(e.RowIndex))
{
RowIndexTracker.Remove(e.RowIndex);
dataGridView1.Rows[e.RowIndex].Selected = false;
}
else
{
RowIndexTracker.Add(e.RowIndex);
}

foreach (int index in RowIndexTracker)
{
dataGridView1.Rows[index].Selected = true;
}
dataGridView1.Enabled = true;
}
}
From: Matthijs de Z on
the line:
>                 dataGridView1.Enabled = true;

should not be there.
From: Peter Duniho on
Matthijs de Z wrote:
> Hi,
>
> I would like to be able to multi select rows in a datagridview, just
> by clicking a cell in the rows I need.
> The code below, does work. But it looks like it might not be the most
> efficient way to do this. When I run the program and select rows, the
> datagrid does not really instantly change, but you can see it
> changing. It's kind of slow, while my machine is not slow at all. Is
> there a more efficient way to do this? Can I let the datagrid stop
> from updating, till the foreach loop is done and then start updating
> again? If so, how can I stop the datagrid from updating / refreshing?

I haven't tried it with the DataGridView and it's possible it doesn't
apply, but maybe the SuspendLayout() and ResumeLayout() methods will do
what you want. They are mainly there for dealing with modifications to
container controls � for example, the TableLayoutPanel, to prevent it
from updating while you're adding child controls � but there's a chance
that DataGridView would use them to suppress/unsuppress refreshing while
the data rows are being updated.

If that doesn't work, then perhaps if you put the data for the
DataGridView itself into a DataSet object. Then when you want to update
the control, create a _new_ DataSet object with the rows you want, and
don't assign the new DataSet object as the data source for the
DataGridView until it's been completely initialized.

Pete
From: Matthijs de Z on
Hi Pete,

> I haven't tried it with the DataGridView and it's possible it doesn't
> apply, but maybe the SuspendLayout() and ResumeLayout() methods will do
> what you want.  

I actually tried these methods, but they didn't really give me what I
wanted. I still have the impression that it is kind of slow.

They are mainly there for dealing with modifications to
> container controls — for example, the TableLayoutPanel, to prevent it
> from updating while you're adding child controls — but there's a chance
> that DataGridView would use them to suppress/unsuppress refreshing while
> the data rows are being updated.

> If that doesn't work, then perhaps if you put the data for the
> DataGridView itself into a DataSet object.  Then when you want to update
> the control, create a _new_ DataSet object with the rows you want, and
> don't assign the new DataSet object as the data source for the
> DataGridView until it's been completely initialized.

If I have a dataset, can I set the rows as selected befor I bound it
to the datagridview or refresh the datagridview?
Regards,

Matthijs

> Pete

From: Peter Duniho on
Matthijs de Z wrote:
> [...]
>> If that doesn't work, then perhaps if you put the data for the
>> DataGridView itself into a DataSet object. Then when you want to update
>> the control, create a _new_ DataSet object with the rows you want, and
>> don't assign the new DataSet object as the data source for the
>> DataGridView until it's been completely initialized.
>
> If I have a dataset, can I set the rows as selected befor I bound it
> to the datagridview or refresh the datagridview?

Sorry�I didn't look closely enough at your original code. No, you can't
use the DataSet to control selection.

However, it certainly seems to me that the code you have to adjust the
current selection could be better. The List<T>.Contains() method will
scan through the entire list if an item isn't present. As the list gets
large (which presumably is when you're seeing performance problems), the
scan could take a non-trivial amount of time, as would trying to
reselect every single row in the list.

I admit, I'm not really sure why you are even using the
"RowIndexTracker" object. What does that give you that simply
inspecting the row's Selected property doesn't? It seems to me that
your click handler really should just look like this:

private void dataGridView1_CellMouseClick(object sender,
DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRow row = dataGridView1.Rows[e.RowIndex];

row.Selected = !row.Selected;
}
}

If at any point you actually need a list of just the rows that are
selected, you can use the DataGridView.SelectedRows property.

Pete