Ошибочное поведение из ContextMenuStrip - PullRequest
2 голосов
/ 06 февраля 2010

Я получаю некоторое странное поведение от ContextMenuStip:

 private void lstModules_MouseMove(object sender , MouseEventArgs e)
 { mouse = e.Location; }
 private void lstModules_MouseDown(object sender , MouseEventArgs e)
 {
  ListViewItem item = null;
  if((hitTest = lstModules.HitTest(mouse)) != null)
   item = hitTest.Item;

  switch (e.Button)
  {
   case MouseButtons.Right:
    if (item != null)
    {
     // valid item selection
     ShowModuleDetails(item.Name);
     lstModules.ContextMenuStrip = mnuContext_Module;
    }
    else
    {
     // right-click - no item selection
     lblModuleDetails.Text = string.Empty;
     lstModules.ContextMenuStrip = mnuContext_Desktop;
    }

    lstModules.ContextMenuStrip.Show(lstModules , mouse);
    break;
   case MouseButtons.Left:
    if (item != null)
    { ShowModuleDetails(item.Name); }
    break;
  }
 }
 private void ShowModuleDetails(string modName)
 {
        //  get module details from dictionary
  lblModuleDetails.Text = Modules[modName].Details;
 }
  1. Элемент в виде списка неправильно выбран, когда отображается контекстное меню. Другими словами, когда элемент выбран, в строке управления меткой отображается подробное строковое значение.
  2. Если отображается контекстное меню и выбран элемент, сведения об этом элементе не изменяются.
  3. Расположение контекстного меню на короткое время появляется в старой позиции мыши, затем перемещается в новую позицию мыши.

Что-то не так с контекстными меню?

1 Ответ

2 голосов
/ 06 февраля 2010

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

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

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

//
// this handler's only responsibility is updating the item info label:
//
void lstModules_ItemSelectionChanged(object sender,
                                     ListViewItemSelectionChangedEventArgs e)
{
    if (e.IsSelected)
    {
        // an item has been selected; update the label, e.g.:
        lblModuleDetails.Text = e.Item.Text;
    }
    else
    {
        // some item has been de-selected; clear the label:
        lblModuleDetails.Text = string.Empty;
    }
}

3. Положение контекстного меню на короткое время появляется в старой позиции мыши, затем перемещается в новую позицию мыши.

Я полагаю, вы пытаетесь сделать слишком много. Позвольте каркасу обрабатывать отображение контекстного меню, которое вы указали через свойство ListView.ContextMenuStrip. Эффект, который вы испытываете, вызывается тем, что вы вручную вызываете ContextMenuStrip.Show(...), что приводит к отображению контекстного меню платформой, а затем вы делаете то же самое во второй раз, в другом месте.

Поэтому старайтесь не вызывать эту функцию; контекстное меню все еще должно появиться.

//
// this handler's only responsibility is setting the correct context menu:
//
void lstModules_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hitTest = lstModules.HitTest(e.Location);
        if (hitTest != null && hitTest.Item != null)
        {
            lstModules.ContextMenuStrip = mnuContext_Module;
        }
        else
        {
            lstModules.ContextMenuStrip = mnuContext_Desktop;
        }
    }
}

Кстати, если это сработает, вы также можете избавиться от вашего lstModules_MouseMove обработчика событий и mouse объекта местоположения.

...