Заметки · 06.05.2022

ListBox и ContextMenuStrip

Эта извечная проблема всех IDE, с которыми мне приходилось сталкиваться: контрол контекстного меню наглухо привязан ко всему listbox’у целиком и заставить его отображать меню только по отношению к item — весёлая задачка. Из коробки таких чудес IDE делать не умеют, а жаль…

Когда-то в Lazarus я решил эту проблему подобным (примерно) образом и этот же метод применил и в среде Visual Studio. Метод прост до безобразия — отключить вызов меню на пустой области и включить там, где нужно, прикрутив проверку наличия выбранного item.

Для начала где-нибудь в public main_form() объявим программное выделение первого (а точнее нулевого) пункта listbox’а:

if (listbox.Items.Count > 0) listbox.SetSelected(0, true);

Дальше создаём метод menu_Opening:

private void menu_Opening(object sender, CancelEventArgs e)
 {
    if (listbox.SelectedItem == null) e.Cancel = true;
    else
            {
                // здесь можно что-то сделать, например, с listbox.SelectedItem.ToString();
            }
 }

Ну, и предсказуемый финал — выделение пунктов списка с помощью клика правой кнопки мыши:

private void listbox_MouseDown(object sender, MouseEventArgs e)
{
   listbox.SelectedIndex = listbox.IndexFromPoint(e.X, e.Y);
}

Думаю, что данный метод вполне применим и к другим разновидностям списков.