2013-09-28 7 views
2

Я испытываю некоторые действительно странное поведение с MenuStrip:MenuStrip не скрывается после щелчка элемента. Ошибка?

  1. Создать новый проект WinForms (.net 4.0 C# или VB.NET не имеет значения, я использовал C#.).
  2. Оставьте заявку MenuStrip по умолчанию. Щелкните правой кнопкой мыши и выберите Вставьте стандартные элементы, чтобы быстро создать его для вас. Этот шаг можно было бы сделать и вручную.
  3. Капля OpenFileDialog на вашей форме.
  4. Добавить обработчик события для DropDownItemClicked событие в меню «Файл». Добавьте в него следующий код:

    private void fileToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) 
    { 
        if (e.ClickedItem.Name == "openToolStripMenuItem") 
        { 
         if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
          MessageBox.Show(openFileDialog1.FileName); 
        } 
    } 
    
  5. Запустить проект. Нажмите на Файл меню, а затем Открыть команда. Появится диалоговое окно файла BUT, меню File не исчезнет. Фактически он рисует сверху OpenFileDialog, скрывая часть его. После того, как вы нажмете Открыть или Отменить в диалоговом окне, и диалоговое окно Файл меню исчезнет.

Почему это так? Это известная ошибка или функция? Я также проверил, что этого не происходит для моих диалоговых окон, только для встроенных диалогов. Вы должны вручную вызвать FileToolStripMenuItem.HideDropDown() перед показом встроенных диалогов.

ответ

2

Это не ошибка. Это функция.

Фактически выпадающее меню будет скрыто автоматически после выполнения кода в обработчике событий DropDownItemClicked. Однако вы используете какой-то MessageBox или ShowDialog, который заблокирует текущее выполнение и повесьте выпадающее меню там.

Для решения этой проблемы существует не менее 2-х решений, один из которых - . Скройте меню самостоятельно, прежде чем показывать диалог (это, кажется, принято вами). Другое решение использует BeginInvoke, чтобы показать ваш диалог, что async вызова не будет блокировать выполнение текущего и выпадающее меню будет скрыт ожидаемо:

private void fileToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e){ 
    if (e.ClickedItem.Name == "openToolStripMenuItem") 
    { 
    BeginInvoke((Action)(()=>{ 
     if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
      MessageBox.Show(openFileDialog1.FileName); 
    })); 
    } 
} 

ПРИМЕЧАНИЯ: скрыть drop down menu вручную в DropDownItemClicked обработчик события, вы можете использовать e.ClickedItem.Owner.Hide() вместо FileToolStripMenuItem.HideDropDown().

+0

Спасибо. +1 для 'Владельца'. Я огляделся по сторонам, но вместо этого искал «Родитель». Асинхронный способ сделать это, однако, не привлекает. Это полностью UI-материал, а не фоновая операция, почему я должен помещать его в другой поток? В общем, элементы структуры поднимают события ПОСЛЕ выполнения их внутреннего управления состоянием, нет? например кнопка вытягивается в освобожденное состояние и только затем вызывает событие «Click». Поэтому я не могу понять, для чего это служит? Никто никогда не захочет отображать элемент меню, принимая некоторые результирующие действия, будь то на основе UI или фона. – dotNET

+0

@dotNET 'BeginInvoke' на самом деле не является потоком, он легковес и часто используется для вызова асинхронных методов, вы должны использовать его при программировании в' winforms' (из-за такой проблемы, как ваша). Я согласен, что такая реализация немного странная. Может быть, поэтому они поддерживают некоторый метод «Скрыть» и «Видимый» для раскрывающегося меню? –

+0

@dotNET Я думаю, что здесь есть причина, связанная с 'побочным эффектом', когда' Click' на самом деле происходит, 'DropDownItemClicked' ** должен быть запущен как можно скорее ** без какой-либо возможности для выполнения какого-либо кода в средний. Предположим, если вы сначала скроете раскрывающееся меню, мы можем добавить некоторое выполнение кода в середине, прежде чем запускать событие DropDownItemClicked, и это даже хуже, чем текущая реализация. По крайней мере, с текущей реализацией мы можем легко исправить так называемую ошибку (по двум решениям, которые я указал). –

 Смежные вопросы

  • Нет связанных вопросов^_^