4

Basically, I have a ListView of items. When one is selected, a text box comes into view on the right to display more details of that item (takes a little time for the item data to be grabbed). The behavior I was going for was to hide this text box on right when all items get unselected.

        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {

            // should only be 1 item selected, it's not a multi-select listview
            ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;

            if (collection.Count == 0) {
                this.label2.Visible = false;
            }    
            foreach (ListViewItem item in collection) {
                this.label2.Visible = true;
                getSideInformation(item.Text);
            }
        }

I noticed a flicker of the box, when I am simply selecting another item. I did some digging by changing my code to:

        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {

            // should only be 1 item selected, it's not a multi-select listview
            ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;

            if (collection.Count == 0) {
                this.label2.Text = "Unselected all!"    
            }
            foreach (ListViewItem item in collection) {
                getSideInformation(item.Text);
            }
        }

Basically, I no longer hide the box, but just change the text if it's a selection change event with 0 items selected. What I found out is that this event actually fires TWICE for a simple select another item (once with 0 items, and a second time with the new items selected). So my box will always display "Unselected all!" while it's loading up any side information if I had previously selected an item and was changing to another item.

Is there any way to differentiate an actual event firing of all items unselected versus that initial firing of 0 items for the selecting another item case?

kharles
  • 326
  • 5
  • 14

5 Answers5

4

You can register to ListView's ItemSelectionChangedEvent instead.

        this.listView1.ItemSelectionChanged += this.HandleOnListViewItemSelectionChanged;

        private void HandleOnListViewItemSelectionChanged(Object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (e.IsSelected)
            {
                this.detailsLabel.Text = this.GetDetails(e.Item);
            }
            else
            {
                this.detailsLabel.Text = String.Empty;
            }
        }
Vijay Sirigiri
  • 4,653
  • 29
  • 31
  • Also never underestimate that the previous guy who worked on the project added an extra event handler. <- my issue. – Brent May 26 '14 at 19:18
  • I tried this and the ItemSelectionChanged event also fires twice. e.IsSelected becomes false, then true, which causes flickering to occur. – myQwil Feb 03 '17 at 21:35
2

The best solution I've found is to temporarily set an event handler to Application.Idle and do your checking from there, like so:

bool handled;
private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
    if (!handled)
    {   handled = true;
        Application.Idle += SelectionChangeDone;   }
}

private void SelectionChangeDone(object sender, EventArgs e) {
    Application.Idle -= SelectionChangeDone;
    handled = false;

    ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;

    if (collection.Count == 0)
        this.label2.Text = "Unselected all!"

    foreach (ListViewItem item in collection)
        getSideInformation(item.Text);
}

It shouldn't matter whether you use ItemSelectionChanged or SelectedIndexChanged. Both will work fine in this case.

Big thanks goes to Grammarian for his answer to essentially the same question here: https://stackoverflow.com/a/26393234/2532220

Community
  • 1
  • 1
myQwil
  • 442
  • 3
  • 11
1

In any control where you can select multiple items, SelectedIndexChanged event fires twice. One, to remove the deselected item and then to add selected item. When you click first time, selected items collection is null and hence it fired once. Next time it will fire twice.

danish
  • 5,550
  • 2
  • 25
  • 28
0

you can use the below code inside the event block to check whether the SelectedIndexChange event is firing directly because of the control or due to some postback event from some other usercontrols/Pages

string id= Request.Form["__EVENTTARGET"];

if(!string.IsNullorEmpty(id))
{
//your code here
}
-1

You can do something like this:

         private bool isInitialized = false;
         private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
             if (isInitialized) {
                 ListView.SelectedListViewItemCollection collection = this.listView1.SelectedItems;

                 if (collection.Count == 0) {
                     this.label2.Text = "Unselected all!";
                 }
                 foreach (ListViewItem item in collection) {
                     getSideInformation(item.Text);
                 }
             }
             isInitialized = true;
        }

That will insure that first firing is ignored.

Vale
  • 3,258
  • 2
  • 27
  • 43
  • the SelectedIndexChanged is being fired twice for every single selection change though (once with 0 items, once with selected item). This doesn't quite allow me to differentiate that once with 0 items with the firing associated with unselecting all items. I played around with a boolean but still couldn't get it to work since in both cases of selecting another item or unselecting al items, the previous state is that something was selected. – kharles Apr 21 '11 at 07:35
  • That is different than, I thought it is firing twice only on loading. I will edit my answer now. – Vale Apr 21 '11 at 07:37
  • I don't get it now. If it fires twice, first time it will set the label text to "Unselected all" and second time it will set it to some other value that you get from getSideInformation() method. So, second value should be displayed. Check your method or edit the question, it is not very clear. – Vale Apr 21 '11 at 07:54