469,578 Members | 1,263 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,578 developers. It's quick & easy.

DataGridView firing way to many SelectionChangedEvents! Please Help

Hi all,

I'm really hoping someone can help me with this as it's causing me some
serious problems.

I have a Windows Forms application using the gridview control. When the
user selects a row, the SelectionChanged event fires and I load some
more data that's particular to that row.

The problem I'm having is that the SelectionChanged event is going way
to many times and this is obviously causing me to load the additional
data scores of times when it's not necessary.

The sorts of things that are causing it to occur are:-
- Refreshing the data
- Calling ClearSelection
- Calling Sort

I can certainly understand why these actions would cause the
SelectionChanged event to fire, but the problem is the sheer number of
times it fires. For example for some reason, when I refresh the binding
source's data, it will fire say, 5 times. Then if I do it again, it will
become 10 times even though I'm clearing the data and not adding to it.
Similarly, when I call sort it seems to cause SelectionChanged to fire
once for each row.

I've tried all sorts of things like detaching event handlers and then
reattaching them after performing a key action but this only helps a
little. Sometimes detaching the event handler doesn't seem to do
anything - the event still fires!

Can anyone help me with some strategy for dealing with this. I'd be
really surprised if I were the only person that was experiencing this so
I'm hoping someone will be able to help me.

Sincerest thanks to anyone who can advise

Best Regards

Simon
Aug 10 '08 #1
6 8115
On Sun, 10 Aug 2008 20:41:23 +0100, Simon Harvey
<no******@hotmail.comwrote:
>Hi all,

I'm really hoping someone can help me with this as it's causing me some
serious problems.

I have a Windows Forms application using the gridview control. When the
user selects a row, the SelectionChanged event fires and I load some
more data that's particular to that row.

The problem I'm having is that the SelectionChanged event is going way
to many times and this is obviously causing me to load the additional
data scores of times when it's not necessary.

The sorts of things that are causing it to occur are:-
- Refreshing the data
- Calling ClearSelection
- Calling Sort

I can certainly understand why these actions would cause the
SelectionChanged event to fire, but the problem is the sheer number of
times it fires. For example for some reason, when I refresh the binding
source's data, it will fire say, 5 times. Then if I do it again, it will
become 10 times even though I'm clearing the data and not adding to it.
Similarly, when I call sort it seems to cause SelectionChanged to fire
once for each row.

I've tried all sorts of things like detaching event handlers and then
reattaching them after performing a key action but this only helps a
little. Sometimes detaching the event handler doesn't seem to do
anything - the event still fires!

Can anyone help me with some strategy for dealing with this. I'd be
really surprised if I were the only person that was experiencing this so
I'm hoping someone will be able to help me.

Sincerest thanks to anyone who can advise

Best Regards

Simon
I assume you mean the DataGridView control. I don't know of any good
solution to this.

Some things I have done to mitigate this are:

Use a subclassed DataGridView. Override the Sort and OnCellClick
methods to determine when the grid is sorting, and in
OnSelectionChanged don't call the base class method to prevent the
SelectionChanged event from occurring.

Clear DataSource before making changes and restoring it afterwards.

Subclass the DataGridView and put code in OnSelectionChanged to try to
notice redundant calls.

Subclass the DataGridView and add a method to set/reset a flag. Call
it to disable the events before making changes and call it to enable
after. Override OnSelectionChanged and if the disable flag is set
don't call the base class OnSelectionChanged.

If the event handler is detached, it is not possible for the event
handler to be called. My guess is either you don't have the detach
and attach paired so that you have it attached more than once, or the
grid is raising the event after you reattach. If you put a breakpoint
on the handler and look at call stack window you should be able to
tell what raised the event. Events occurring later than you expect is
a big problem when the grid is first being instantiated - many grid
events are delayed until the grid becomes visible.
Aug 10 '08 #2
Hi Jack,

Thank you ver much for your reply. I have been trying various
incarantions of these suggestions though I haven't gone as far as trying
to subclass the control.

Quick question. When you say:
"Clear DataSource before making changes and restoring it afterwards."
How do I do this exactly? At the moment I just get my datatable and then
assign it to my BindingSource's DataSource property. e.g.

tblPlaces = tableAdapter.SelectAll();
bsPlacesBindingSource.DataSource = tblPlaces;

This works but each time the number of SelectionChanged events that are
fired increases, which I don't understand. It's almost as though behind
the scenes the number of rows is quietly increasing each time, but that
doesn't appear to be the case because the grid continues to display the
correct number of rows (eventually!)

I'm wondering from your reply if there is a better way to refresh the
data that my bindingsourece or datagridview is using?

Many thanks again for your help

Simon
Aug 11 '08 #3
Hi Jack,

Thank you ver much for your reply. I have been trying various
incarantions of these suggestions though I haven't gone as far as trying
to subclass the control.

Quick question. When you say:
"Clear DataSource before making changes and restoring it afterwards."
How do I do this exactly? At the moment I just get my datatable and then
assign it to my BindingSource's DataSource property. e.g.

tblPlaces = tableAdapter.SelectAll();
bsPlacesBindingSource.DataSource = tblPlaces;

This works but each time the number of SelectionChanged events that are
fired increases, which I don't understand. It's almost as though behind
the scenes the number of rows is quietly increasing each time, but that
doesn't appear to be the case because the grid continues to display the
correct number of rows (eventually!)

I'm wondering from your reply if there is a better way to refresh the
data that my bindingsourece or datagridview is using?

Many thanks again for your help

Simon
Aug 11 '08 #4
On Mon, 11 Aug 2008 11:35:09 +0100, Simon <no******@hotmail.com>
wrote:
>Hi Jack,

Thank you ver much for your reply. I have been trying various
incarantions of these suggestions though I haven't gone as far as trying
to subclass the control.

Quick question. When you say:
>"Clear DataSource before making changes and restoring it afterwards."

How do I do this exactly? At the moment I just get my datatable and then
assign it to my BindingSource's DataSource property. e.g.

tblPlaces = tableAdapter.SelectAll();
bsPlacesBindingSource.DataSource = tblPlaces;

This works but each time the number of SelectionChanged events that are
fired increases, which I don't understand. It's almost as though behind
the scenes the number of rows is quietly increasing each time, but that
doesn't appear to be the case because the grid continues to display the
correct number of rows (eventually!)

I'm wondering from your reply if there is a better way to refresh the
data that my bindingsourece or datagridview is using?

Many thanks again for your help

Simon
My suggestion was to set the grid's DataSource to Nothing, make the
changes to the data source, then set the DataSource back to what it
was before. I don't use TableAdapters so I don't have any experience
with them.
Aug 11 '08 #5
OK - I'll give that a shot - thank you

Simon
Aug 11 '08 #6
Hi Simon,
I had a similar problem, my solution was something like

bool canDoThat = true;

private void dgv_SelectedChanged(object sender, Event e) {
if (!canDoThat) return;
canDoThat = false;
... // do whatever you need to do
canDoThat = true;
}

Note: it is not thread-safe solution. If you use threads, you would
need some locking on canDoThat variable, I guess.

Cheers
Ondra
--
http://xmedeko.blogspot.com
Aug 15 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by DraguVaso | last post: by
10 posts views Thread by Henok Girma | last post: by
reply views Thread by Paul Cheetham | last post: by
7 posts views Thread by Mitchell S. Honnert | last post: by
2 posts views Thread by Ian Semmel | last post: by
3 posts views Thread by Andrus | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.