most efficient way for multiselect in datagridview

M

Matthijs de Z

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;
}
}
 
P

Peter Duniho

Matthijs said:
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
 
M

Matthijs de Z

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
 
P

Peter Duniho

Matthijs said:
[...]
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
 
M

Matthijs de Z

Pete said:
 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;
     }
   }

Hi Pete,

thanks for looking into the problem.

with the code above, I'm not able to select multiple rows by just
clicking them. That’s why I used the List (to keep track of rows
already selected, or in case you click on a row again, deselect it).

the thing is, that when i click on a cell in a row, i can see that it
takes some time to select the whole row. It's not done
instantaneously. And the thing is....I can only see it on the row I
click on....the other rows (even those who are already selected) don't
show this behavior.

I'll play around with it today some more. If I found out what the
problem was, I'll post it here.
Regards,

Matthijs
 
M

Matthijs de Z

Pete,

I've changed the project and now use a axtra column with a checkbox.
When you click a row, the checkbox will be checked (or unchecked) and
I will not use multiple selections anymore.
regards,

Matthijs
 
P

Peter Duniho

Matthijs said:
Pete,

I've changed the project and now use a axtra column with a checkbox.
When you click a row, the checkbox will be checked (or unchecked) and
I will not use multiple selections anymore.
regards,

I would expect that there's a way for you to override the selection
behavior when clicking (I assume the problem you mean is that the
control is already unselecting the current selection on a plain click).
Having done that, the code I suggested should work fine.

But a check box should be fine too, if you're happy with that.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top