Отмена события ListBox SelectedIndexChange

Можно ли отменить событие SelectedIndexChange для списка в приложении winforms? Кажется, это настолько логично, что я должен забыть о какой-то простой функции. В основном, у меня появилось окно с сообщением о том, действительно ли пользователь хочет перейти на другой элемент, так как это изменит пользовательский интерфейс, и я не хочу, чтобы их изменения были потеряны. Я хотел бы иметь возможность отменить событие, если пользователь не сохранил то, над чем они работают. Есть ли лучший способ сделать это?

Ответы

Ответ 1

Вы не можете отменить его.

То, что я сделал всего пару дней назад, состояло в том, чтобы иметь переменную с последним выбранным индексом. Затем, когда событие срабатывает, вы спрашиваете пользователя, хочет ли он сохранить его, это делается в обработчике событий. Если пользователь выбрал "Отмена", вы снова меняете идентификатор.

Проблема в том, что это снова запустит событие. Так что я использовал bool, просто говоря "Запретить". И в верхней части обработчика событий я:

if(Inhibit)
   return;

Затем ниже, где вы задаете вопрос, вы делаете что-то вроде этого:

DialogResult result = MessageBox.Show("yadadadad", yadada cancel etc);
if(result == DialogResult.Cancel){
   Inhibit = true; //Make sure that the event does not fire again
   list.SelectedIndex = LastSelectedIndex; //your variable
   Inhibit = false; //Enable the event again
}
LastSelectedIndex = list.SelectedIndex; // Save latest index.

Ответ 2

Это точно метод @Oskar Kjellin, но с завихрением. То есть, одна переменная меньше и с выбранным индексом изменяет событие, которое действительно ведет себя как событие с измененным индексом. Я часто задаюсь вопросом, почему выбрано событие с измененным индексом, которое срабатывает, даже если я нажму на тот же выбранный элемент. Здесь нет. Да, это отклонение, поэтому будьте вдвойне уверены, хотите ли вы, чтобы это было там.

    int _selIndex = -1;
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (listBox1.SelectedIndex == _selIndex)
            return;

        if (MessageBox.Show("") == DialogResult.Cancel)
        {
            listBox1.SelectedIndex = _selIndex;
            return;
        }

        _selIndex = listBox1.SelectedIndex;
        // and the remaining part of the code, what needs to happen when selected index changed happens
    }

Ответ 3

Я столкнулся с этой точной проблемой. Что я сделал, когда пользователь вносит изменения, я устанавливаю ListBox.Enabled = false; Это запрещает им выбирать другой индекс. Когда они либо сохраняют, либо отбрасывают свои изменения, я устанавливаю ListBox.Enabled = true; Вероятно, это не так гладко, как подсказка, но она выполняет свою работу.

Ответ 4

Более элегантно, используйте свойство Tag:

        if ((int)comboBox.Tag == comboBox.SelectedIndex)
        {
            // Do Nothing
        }
        else
        {
            if (MessageBox.Show("") == DialogResult.Cancel)
            {
                comboBox.SelectedIndex = (int)comboBox.Tag;
            }
            else
            {
                // Reset the Tag
                comboBox.Tag = comboBox.SelectedIndex;

                // Do what you have to
            }
        }

Ответ 5

Выделение SelectedIndexChanged не может быть отменено. Таким образом, у вас есть только один реальный вариант:

private int? currentIndex;
public void ListBox_SelectedIndexChanged(sender, EventArgs args) {
    if (currentIndex.HasValue && currentIndex.Value != listBox1.SelectedIndex) {
        var res = MessageBox.Show("Do you want to cancel edits?", "Cancel Edits", MessageBoxButtons.YesNo);
        if (res == DialogResult.Yes) {
            currentIndex = (listBox1.SelectedIndex == -1 ? null : (int?) listBox1.SelectedIndex);
        } else {
            listBox1.SelectedIndex = currentIndex.Value;
        }
    }
}

Ответ 6

Это мой способ отменить SelectionChange для ComboBox. Я думаю, он также может соответствовать ListBox.

private bool comboBox_CancelSelection = false;
private int comboBox_LastSelectedIndex = -1;

private void comboBox_SelectedIndexChanged(object sender, EventArgs e) {
    if (comboBox_CancelSelection) {
        comboBox_CancelSelection = false;
        return ;
    }

    // Handle Event

    if (!comoBox_CancelSelection) {
        comboBox_LastSelectedIndex = comboBox.SelectedIndex; 
    } else {
        comboBox.SelectedIndex = comboBox_LastSelectedIndex;
    }
}