ListView's SelectedIndexChanged overfiring -> time for new AfterSelectedIndexChanged event?

  • Thread starter Thread starter Fizgig
  • Start date Start date
F

Fizgig

I have a ListView control and based on the item selection, another
control is updated. That update process is relatively slow.

I subscribed to the selectedindexchanged event, but that event is not
really helpfull in my case as it fires twice for every change in the
selection, once for clearing the selection and once for adding the new
selected item.

As I allow multiple selections, this is even worse (10 or 11 events
when you select 10 items, depending on your initial state).

What I need is a AfterSelectedIndexChanged event, but without access
to the source I'm not sure what's the best way to fake this.

Any thoughts?
 
Fizgig said:
I have a ListView control and based on the item selection, another
control is updated. That update process is relatively slow.

I subscribed to the selectedindexchanged event, but that event is not
really helpfull in my case as it fires twice for every change in the
selection, once for clearing the selection and once for adding the new
selected item.

As I allow multiple selections, this is even worse (10 or 11 events
when you select 10 items, depending on your initial state).

What I need is a AfterSelectedIndexChanged event, but without access
to the source I'm not sure what's the best way to fake this.

Any thoughts?

Set a bflag and use it in the event to bypass the code in the event. You
know the conditions when the event is firing so bypass the code in the
event, by setting the bflag = true. The only time you want the code in
the event to execute is when someone makes a selection and not because
you're loading the Listbox or clearing the Listbox. After the load or
clearing of the Listbox, you set bflag = false.


if not bflag = true then
execute the code in the event
else
bypass the code execution.
 
Set a bflag and use it in the event to bypass the code in the event. You
know the conditions when the event is firing so bypass the code in the
event, by setting the bflag = true. The only time you want the code in
the event to execute is when someone makes a selection and not because
you're loading the Listbox or clearing the Listbox. After the load or
clearing of the Listbox, you set bflag = false.

if not bflag = true then
execute the code in the event
else
bypass the code execution.

HI darnold,

My problem is that the process "someone makes a selection" is an
atomic process when using the listview selectedindexchange event:
there is no easy way of determining whether more selectedindexchanged
events are going to be fired or not.

So, if that would be possible, i could skip the processing of all
selectedindexchanged events but one in the way you proposed.
 
Every time you deal with that Listview, you are loading the Listview with
items, clearing it, or a user makes a selection, the selectedindexchange
event is going to firer.

You know when it's being loaded and you know when it's being cleared. So if
you know these things and the area of the code where you are doing these
things, you set the flag to bypass the code in the event and set the flag
to not bypass when these things are completed.

If the flag is setting at not bypass, it's because your code at the area of
loading and clearing the Listview has completed its task and set the flag.

Anytime after the tasks above of loading and clearing are completed with
the area of code setting the flag to not bypass, it will be someone making a
selection that caused the event to fire and the code will be executed.

When you're loading and clearing, set the flag to bypass. When you're done
with loading and clearing, set the flag to not bypass.
 
The flag works for the OnLoad event of the windows form / web form / mobile form.
In a single select Listview, not multi-select, the following code is simple to implement, and prevents multiple firing of the event.

As the ListView deselects the first item, the second item it what you need and the collection should only ever contain one item.

The same below was used in a mobile application, therefore some of the collection names might be different as it is using the
compact framework.

Note: Make sure OnLoad and populate of the listview you set the first item to be selected.

################ CODE STARTS HERE ################
//Flag to create at the form level
System.Boolean lsvLoadFlag = true;

//Make sure to set the flag to true at the begin of the form load and after
private void frmMain_Load(object sender, EventArgs e)
{
//Prevent the listview from firing crazy in a single click NOT multislect environment
lsvLoadFlag = true;

//DO SOME CODE....

//Enable the listview to process events
lsvLoadFlag = false;
}

//Populate First then this line of code
lsvMain.Items[0].Selected = true;

//SelectedIndexChanged Event
private void lsvMain_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem lvi = null;

if (!lsvLoadFlag)
{
if (this.lsvMain.SelectedIndices != null)
{
if (this.lsvMain.SelectedIndices.Count == 1)
{
lvi = this.lsvMain.Items[this.lsvMain.SelectedIndices[0]];
}
}
}
}
################ CODE END HERE ################

Ideally, this code should be put into a UserControl for easy re-use and distrbution in a single select ListView.

Kind regards,

Anthony N. Urwin
http://www.manatix.com
 
Back
Top