Заголовок ListView ItemChanged с MessageBoxes - ItemSelectionChanged вызывается дважды - PullRequest
2 голосов
/ 08 июня 2011

Вот проблема: у меня есть приложение для Windows Forms, которое я разрабатываю, и в одном сегменте я использую элемент управления ListView.

То, что я пытаюсь сделать, можно просто сформулировать так: при событии ListViewItemSelectionChange показать MessageBox для пользователя, чтобы подтвердить изменение, если не подтверждено изменение, скажем, для первого элемента. Это изменение первого элемента снова вызовет ListViewItemSelecionChange, поэтому я отменяю регистрацию и перерегистрирую метод обработчика событий, поэтому все должно быть хорошо, верно?

На самом деле происходит то, что метод-обработчик вызывается дважды (на самом деле ListView должен вызывать два события при изменении выделения, одно для отмены выбора, другое для вновь выбранного элемента, но в начале у меня есть оператор e.IsSelected для отлова только выбранные предметы, так что на самом деле можно сказать, что произошло четыре события).

Проблема в том, что если я сгенерировал первое событие щелчком мыши по элементу ListView, и я отменил подписку, прежде чем программно перейти к первому элементу, что генерирует запуск второго события? Это какое-то изменение фокуса из-за вызова MessageBox? Есть ли способ предотвратить запуск второго события?

У меня есть простое примерное решение, оно не может быть более упрощенным (25 SLOC ), поэтому, если вы можете, пожалуйста, посмотрите. Обратите внимание, что комментирование строки «if (ShowMessageBox ())» останавливает запуск второго события, является ли это некоторой проблемой изменения фокуса?

http://www.filedropper.com/listviewtestwithmsgbox

Редактировать: соответствующий код:

private void listViewWithSelection1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    // listview actually generates two ItemSelectionChanged events,
    // one for deselect of a item, and another event for a newly selected item (which we want here).
    if (e.IsSelected)
    {
        if (ShowMessageBox())
            Button1_Click(null, EventArgs.Empty);

        label1.Text += "item selected   ";
    }
}

private bool ShowMessageBox()
{
    return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes;
}

private void Button1_Click(object sender, EventArgs e)
{
    // change ti first ListView item
    listView1.ItemSelectionChanged -= listViewWithSelection1_ItemSelectionChanged;
    listView1.Items[0].Selected = true;
    listView1.ItemSelectionChanged += listViewWithSelection1_ItemSelectionChanged;
}

Ответы [ 2 ]

1 голос
/ 08 июня 2011

Хм, можете ли вы описать, как выбор изменяется с самого начала? Если пользователь щелкает, чтобы выбрать элемент, возможно, поймать событие Click или DoubleClick, а не событие ItemSelectionChanged? У меня есть этот фрагмент, который я сейчас использую в программе. Если пользователь дважды щелкает окно списка (в вашем случае listView), сделайте что-нибудь с выбранным элементом.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private bool ShowMessageBox()
    {
        return MessageBox.Show("Change to first item instead?", "test", MessageBoxButtons.YesNo) == DialogResult.Yes;
    }

    private void listView1_Click(object sender, EventArgs e)
    {
        if (ShowMessageBox())
            listView1.TopItem.Selected = true;
            label1.Text += "item selected   ";
    }
}

Отредактировано для включения соответствующего кода.

1 голос
/ 08 июня 2011

Один из способов сделать это - установить флаг, который говорит, что должен запускаться код изменения.

В вашем коде ListViewItemSelecionChange вы проверяете значение флага и соответственно запускаете код.

...