C# ListView - Обнаружение, когда пользователь отменяет выбор элемента или выбирает новый

Я пытаюсь определить, когда пользователь выбирает новый элемент в ListView и когда он отменяет выделение всего (щелкая пустую область в ListView), но мне трудно это сделать правильно. Мне нужно это, чтобы включить или отключить пару кнопок "Переместить элемент вверх" и "Переместить элемент вниз". Я думаю, что лучший способ сделать это, чтобы справиться с ItemSelectionChanged событие, так что у меня есть это, что кажется довольно очевидным:

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

Он отлично работает, когда пользователь отменяет выбор всего, но проблема в том, что это событие запускается дважды, когда пользователь выбирает другой элемент: один раз для отмены выбора текущего элемента и другой для выбора нового. Это вызывает некоторое мигание на кнопках "Переместить элемент вверх" и "Переместить элемент вниз", потому что это сначала отключит кнопки (потому что текущий элемент был отменен), а затем снова активирует их (когда выбран новый элемент).

Кто-нибудь знает, как я могу решить эту проблему? У меня закончились идеи.

Заранее спасибо.

3 ответа

Вы пытались использовать lstItems_SelectedIndexChanged вместо lstItems_ItemSelectionChanged? Я верю, что это сработает только 1 раз. Надеюсь, это поможет!

Я никогда не использовал listView, но я думаю, что вы можете удалить другую часть метода lstItems_ItemSelectionChanged, а затем, если часть, вы можете сначала отключить все кнопки, а затем добавить только две связанные кнопки. Событие lstItems_ItemSelectionChanged запускается два раза: первый раз "если" не срабатывает и второй раз "если" срабатывает. так что ваша проблема будет решена.

Я хотел, чтобы мое представление списка отключало две кнопки, когда список был отключен. Следующий код добился этого.

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;
}

Лучшее решение, которое я нашел, это временно установить обработчик событий в Application.Idle и сделайте свою проверку оттуда, вот так:

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;
}

Не важно, используете ли вы ItemSelectionChanged или же SelectedIndexChanged, Оба будут хорошо работать в этом случае.

Большое спасибо Грамматику за его ответ на практически тот же вопрос здесь: /questions/38415262/kak-vyibor-iz-spiska-izmenil-rabotu-sobyitiya-eto-nazyivaetsya-twise/38415272#38415272

Другие вопросы по тегам