2

I'm trying to detect when the user selects a new item in a ListView and when he deselects everything (by clicking on an empty area on the ListView), but I'm having a hard time getting it right. I need this to enable or disable a couple of "Move item up" and "Move item down" buttons. I think the best way to do this is to handle the ItemSelectionChanged event, so I have this, which seems pretty obvious:

private void lstItems_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) {
    if (e.IsSelected) {
        cmbMoveUp.Enabled = true;
        cmbMoveDn.Enabled = true;
    } else {
        cmbMoveUp.Enabled = false;
        cmbMoveDn.Enabled = false;
    }
}

It works fine when the user deselects everything, but the problem is that this event is fired twice when the user selects another item: one time for deselecting the current item and another for selecting the new one. This causes some blinking on the "Move item up" and "Move item down" buttons, because it will first disable the buttons (because the current item was deselected) and then enable them again (when the new item is selected).

Anyone knows how can I solve this issue? I've ran out of ideas.

Thanks in advance.

Fergo
  • 57
  • 7
  • OK. Sorry for the confusion. I have used ListView tons of times and never relied on the ItemSelectionChanged event; neither on IsSelected. I did a quick search for this last property and all the results I saw referred to WPF. – varocarbas Jan 05 '14 at 09:34
  • Regarding your problem, your code does exactly what is expected to do: it performs the given actions when a "tracked deselection" (clicking somewhere else WITHIN the ListView) occurs. The problem you refer is an unaccounted situation: if you click on another item, your code can track this change, but what should it do? Two actions happen (one item is selected and the other one is unselected), what should be done? enabling or disabling? Thus, there is nothing wrong with your code, but with your ideas. Please, explain clearly what you want to happen in each scenario and you might get some help. – varocarbas Jan 05 '14 at 09:46
  • Sorry for not being very clear. As you said, the code works, and at the end of the day, it does what it should do. The "problem" (more of a quirk actually) is that when another item is selected, it will fire one time due to the deselecting of the current item (disabling the buttons) and, right after this, fire once again due to the newly selected item, enabling the buttons. This two sequential events happens pretty fast of course, but it's "slow" enough for you to see the buttons getting disabled and enabled again every time you select another item on the list view. (cont) – Fergo Jan 07 '14 at 01:18
  • What I need is some way to **not** disable the buttons if the user selects a different item (like discarding the first of the two events or something like that) but still disable them if the user deselects everything (when the event is only raised one time). PS.: I'm quite new to posting on SO, please let me know if I should edit the OP and add this information there or keep it here. – Fergo Jan 07 '14 at 01:18
  • Now it is much clearer (please, take a look at my answer). I do think that you should edit your question to explain clearly what you are after. – varocarbas Jan 07 '14 at 09:57
  • As far as a pathetic, ignorant coward has -1ed my answer (the only right one you got). And you have shown a pretty pathetic behaviour by not answering the only person giving you the right solution, I will delete my answer, let this comment here and not help you ever (neither any other of the "answerers" here). Also I have found very very, very weird the fact that my comment in Wind up Beanie "answer" (a senseless statement) was deleted (and then, after my complain, magically written back)... mainly the fact that only SO can do such a thing. – varocarbas Jan 08 '14 at 11:53

4 Answers4

0

I never used listView, but I think you can remove else part of lstItems_ItemSelectionChanged method, then in if part you can first disable all buttons and then enale just two related buttons. lstItems_ItemSelectionChanged event fires two time, first time "if" does'nt fire and second time "if" will fire. so your problem will be solved.

Katy
  • 286
  • 2
  • 18
  • Thanks, but then it would not disable the buttons when the user deselects everything, since in that case, the e.Select will be false. – Fergo Jan 04 '14 at 21:45
  • The name of the control is ListView and, perhaps, you shouldn't write an answer if you don't have any experience with the given situation (people asking here expects somehow knowledgeable programmers, at least, in this specific matter to answer). As commented in the answer above, your "solution" does not make any sense and, purely speaking, does not deserve +1 (IMO). Think carefully about the problem (feel free to take a look at my comments on the OP's question which clarify the issue further) and consider to re-write your suggestion. – varocarbas Jan 05 '14 at 09:52
  • I -1ed you because your answer does not make any sense. As far as someone has -1ed mine which was perfectly right (+ something else pretty weird which has happened here), I have preferred to not apply the rules I usually apply and -1 everything here (because of being objectively bad, no revenge at all; usually I am understanding, but what is the point of being understanding under these conditions?). – varocarbas Jan 08 '14 at 11:56
0

Have you tried using lstItems_SelectedIndexChanged instead of lstItems_ItemSelectionChanged? I believe that would only trigger this 1 time. Hope that helps!

  • You are not understanding the problem here (feel free to read my comments above to clarify your ideas): the behaviour which the OP wants to track (the posted if-else every time an item is selected/deselected) implies that it will be reached twice when the deselection of an item occurs because of selecting a different one. The problem here is that OP's ideas are not too clear. – varocarbas Jan 05 '14 at 09:49
0

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 lstItems_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) {
    if (!handled)
    {   handled = true;
        Application.Idle += SelectionChangeDone;   }
}

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

    if (lstItems.SelectedItems.Count > 0)
         cmbMoveUp.Enabled = cmbMoveDn.Enabled = true;
    else cmbMoveUp.Enabled = cmbMoveDn.Enabled = false;
}

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
0

I wanted my list view to disable two buttons when the list was de-selected. The following code achieved this.

private void Session_List_SelectedIndexChanged(object sender, EventArgs e) {
    bool toggle = true;
    if (Session_List.SelectedItems.Count == 0) {
        toggle = false;
    }

    Selected_Task.Enabled = toggle;   
    Perform_Task.Enabled = toggle;
}
Thomas Jones
  • 107
  • 4