By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,909 Members | 2,016 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,909 IT Pros & Developers. It's quick & easy.

c# ListView selection change

P: n/a
Hi all!

I have a problem (performance issue) with listview. I have implemented an
ItemSelectionChange on my listview and put some code in it (I build some
toolbar based on selection and update info in statusbar). When selecting one
item (clicking on listview) it works fast, without noticing. However if
selecting multiple items with SHIFT (approx. 500 items) or selecting with
mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app (the
code running 500 times instead of one time - OnSelectionEnd or sth.). Is it
possible to have an event or simulate it only when selection is finished
(e.g. when all 500 items are selected) not for each and every one?

Thanks in advance!

Best regards,
Jure
Oct 16 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Jure Bogataj wrote:
[...] However if
selecting multiple items with SHIFT (approx. 500 items) or selecting with
mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app (the
code running 500 times instead of one time - OnSelectionEnd or sth.). Is it
possible to have an event or simulate it only when selection is finished
(e.g. when all 500 items are selected) not for each and every one?
I'm not sure, not having run into this particular problem myself.
However, here's a thought: in the same class with the event handler,
include a boolean variable indicating whether or not a selection-changed
event is being handled.

Then, the first thing you do is check the flag. If it's set, you do
nothing. If it's not set, you set it and use BeginInvoke() with a
method that should do the actual selection-changed handling.

Then in that method, the one that does the actual selection-changed
handling, you clear the flag again. As well as do whatever handling it
is you want to do, of course.

This will ensure that no new handling is done until you've had a chance
to process the current selection-changed event. The handling won't be
done inline with the user-interaction, and any user input that happens
before you have that chance will not cause a new attempt to handle the
event.

Whether this will actually address your concern, I'm not sure. Your
post isn't very clear about the specific user action or actions that
you're trying to deal with, nor is it clear why your event handling is
so costly that it causes a noticeable delay.

If the above isn't helpful, you should consider being more specific
about your question. This would include posting a concise-but-complete
sample of code that reliably demonstrates the issue. You will also want
to post very specific instructions for how to use the code, since
apparently user behavior is important in the issue.

Pete
Oct 16 '07 #2

P: n/a
Liz

"Jure Bogataj" <ju**********@mikrocop.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hi all!

I have a problem (performance issue) with listview. I have implemented an
ItemSelectionChange on my listview and put some code in it (I build some
toolbar based on selection and update info in statusbar). When selecting
one item (clicking on listview) it works fast, without noticing. However
if selecting multiple items with SHIFT (approx. 500 items) or selecting
with mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app (the
code running 500 times instead of one time - OnSelectionEnd or sth.). Is
it possible to have an event or simulate it only when selection is
finished (e.g. when all 500 items are selected) not for each and every
one?
Peter's already given you an approach to that but ... how does the program
"know" that "selection is finished" ?

I don't have any problem handling the event and doing something simple with
it (displaying the number of items selected on a Label, for example); if
your handler is complex, perhaps you can defer the action taken in your
handler until the user does *something else* ... e.g.: user selects item 2,
item 17, item 10 and then clicks an "Act on Selection(s)" button ... of
course in that case you don't need to use the ItemSelectionChange event at
all

If you don't want user intervention perhaps you could check the value of
ListView.SelectedIndeces every N seconds (not my own favorite idea)

L

Oct 16 '07 #3

P: n/a
"Jure Bogataj" <ju**********@mikrocop.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hi all!

I have a problem (performance issue) with listview. I have implemented an
ItemSelectionChange on my listview and put some code in it (I build some
toolbar based on selection and update info in statusbar). When selecting
one item (clicking on listview) it works fast, without noticing. However
if selecting multiple items with SHIFT (approx. 500 items) or selecting
with mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app (the
code running 500 times instead of one time - OnSelectionEnd or sth.). Is
it possible to have an event or simulate it only when selection is
finished (e.g. when all 500 items are selected) not for each and every
one?

Thanks in advance!

Best regards,
Jure
Hi Jure,

It is possible to create a new event like that, and handle it, but it would
be extremely difficult. You would have to track down all of the windows
messages that could potentially cause a selection change, and manage them.
There's a lot of behavior managing the selection of items in the listview.
For example, you can move the focus rectangle while holding the 'Ctrl' key,
and then select individual items with the spacebar.

A better way perhaps for you would be to put a minimal delay in your
ItemSelectionChange Handler. Say -- 50ms. Use a timer, Once the selection
changes, restart the timer. If the selection changed more than once within
the delay period, then the original is ignored, but after the delay has
expired, the logic is executed.

Like this:

public class SelectionEndListView : ListView
{
private System.Windows.Forms.Timer m_timer;
private const int SELECTION_DELAY = 50;

public SelectionEndListView()
{
m_timer = new Timer();
m_timer.Interval = SELECTION_DELAY;
m_timer.Tick += new EventHandler(m_timer_Tick);
}

protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);

// restart delay timer
m_timer.Stop();
m_timer.Start();
}

private void m_timer_Tick(object sender, EventArgs e)
{
m_timer.Stop();

// Perform selection end logic.
Console.WriteLine("Selection Has Ended");
}
}

-- Matt

Oct 16 '07 #4

P: n/a
Thank you all for your replies. I will try to implement this with timer. I
think 50ms is not too long for user to notice that toolbar doesn't get
changed immediately.
Thanks again!

Best regards,
Jure

"Jure Bogataj" <ju**********@mikrocop.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
Hi all!

I have a problem (performance issue) with listview. I have implemented an
ItemSelectionChange on my listview and put some code in it (I build some
toolbar based on selection and update info in statusbar). When selecting
one item (clicking on listview) it works fast, without noticing. However
if selecting multiple items with SHIFT (approx. 500 items) or selecting
with mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app (the
code running 500 times instead of one time - OnSelectionEnd or sth.). Is
it possible to have an event or simulate it only when selection is
finished (e.g. when all 500 items are selected) not for each and every
one?

Thanks in advance!

Best regards,
Jure

Oct 17 '07 #5

P: n/a
Thank you! Works very well with timer. A lot faster than before.

Best regards,
Jure
"Matt Brunell" <ma**@fast-soft.comwrote in message
news:%2****************@TK2MSFTNGP04.phx.gbl...
"Jure Bogataj" <ju**********@mikrocop.comwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>Hi all!

I have a problem (performance issue) with listview. I have implemented an
ItemSelectionChange on my listview and put some code in it (I build some
toolbar based on selection and update info in statusbar). When selecting
one item (clicking on listview) it works fast, without noticing. However
if selecting multiple items with SHIFT (approx. 500 items) or selecting
with mouse, for each item selected through all listview an event
(ItemSelectionChange) gets called. And this is what slows down my app
(the code running 500 times instead of one time - OnSelectionEnd or
sth.). Is it possible to have an event or simulate it only when selection
is finished (e.g. when all 500 items are selected) not for each and every
one?

Thanks in advance!

Best regards,
Jure

Hi Jure,

It is possible to create a new event like that, and handle it, but it
would be extremely difficult. You would have to track down all of the
windows messages that could potentially cause a selection change, and
manage them. There's a lot of behavior managing the selection of items in
the listview. For example, you can move the focus rectangle while holding
the 'Ctrl' key, and then select individual items with the spacebar.

A better way perhaps for you would be to put a minimal delay in your
ItemSelectionChange Handler. Say -- 50ms. Use a timer, Once the
selection changes, restart the timer. If the selection changed more than
once within the delay period, then the original is ignored, but after the
delay has expired, the logic is executed.

Like this:

public class SelectionEndListView : ListView
{
private System.Windows.Forms.Timer m_timer;
private const int SELECTION_DELAY = 50;

public SelectionEndListView()
{
m_timer = new Timer();
m_timer.Interval = SELECTION_DELAY;
m_timer.Tick += new EventHandler(m_timer_Tick);
}

protected override void OnSelectedIndexChanged(EventArgs e)
{
base.OnSelectedIndexChanged(e);

// restart delay timer
m_timer.Stop();
m_timer.Start();
}

private void m_timer_Tick(object sender, EventArgs e)
{
m_timer.Stop();

// Perform selection end logic.
Console.WriteLine("Selection Has Ended");
}
}

-- Matt

Oct 17 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.