Windows forms как сделать выпадающее меню

Обновлено: 04.07.2024

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


Первоначально, создайте новый проект, указав в качестве шаблона Windows Form Application и назовите second_application. Затем нажмите OK.


Здесь все предельно просто: чтобы добавить меню в приложение, сначала откройте окно Toolbox (Панель элементов).
Нам потребуется разворот Menus & Toolbars (Меню и панели инструментов). В нем нас интересует элемент MenuStrip (рис. 1).
Рисунок 1. Выбор элемента для созданию меню.
Зажмите его левой клавишей мыши и перетащите на форму. На нашей форме отразиться элемент меню, как показано на рисунке 2.
Рисунок 2. Создание элементов меню.
Теперь, щелкнув на строке «введите здесь» вы можете ввести название меню: назовем его «File». При этом добавятся 2 дополнительных элемента – один снизу, он будет доступен при открытии меню, второй справа - для создания новых разделов меню (рис. 3).
Рисунок 3. Процесс добавления элементов меню.

Перед нами откроется код функции обработчика:


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

Новый код функции с комментариями:

Теперь можно откомпилировать приложение и проверить работоспособность кнопки.

Часто панель управления (Toolbar) дублирует элементы меню для быстрого к ним доступа.

Нам снова нужно перейти к окну Toolbox (Панель инструментов) и развороту Menus & Toolbars. В этот раз мы выберем элемент ToolStrip (рис. 5).
Рисунок 5. Окно Toolbox.
Перетащите элемент управления на окно и вы увидите, как вдоль его верхней границы разместиться панель ToolBar (рис. 6).
Рисунок 6. Добавленный элемент Toolbar.
Мы изменим положение привязки нашего ToolBar’a. Для этого щелкнем по нему правой кнопкой и в открывшемся контекстном меню выберем пункт Свойства. Откроется окно свойств: здесь мы изменим привязку на левую часть окна, внеся изменения в параметр Dock, как показано на рисунке 7.
Рисунок 7. Привязка панели инструментов к левой стороне.
Теперь увеличим размеры кнопок на Toolbar'e. Для этого сначала необходимо в его свойствах установить параметр AutoSize равным false. Теперь мы можем изменить размеры самих кнопок: установим параметры Size - Width равным 44. Поле станет шире (рис. 8).
Рисунок 8. Установка размеров изображений, размещаемых на кнопках создаваемого Toolbar.
Теперь добавим 3 кнопки на наш ToolBar. Для этого щелкните по нему и в раскрывающемся списке элементов, которые мы можем добавить, выберите элемент button (рис. 9).
Рисунок 9. Добавление кнопок на панель элементов (Toolbar).
Повторите операцию, чтобы кнопок на панели стало две. Теперь поочередно выберите каждую кнопку и в ее свойствах установите AutoSize равный false. После это перейдите к полю Size и установите высоту равную 42. Теперь кнопки примут квадратный вид.

Мы будем использовать 3 следующих изображения:


Изображение для кнопки 1: будет назначено кнопке, отвечающей за открытие дополнительного диалогового окна.

Два следующих изображения будут назначены кнопкам, которые будут отвечать за загрузку файлов jpg и png.


Изображение для кнопки 2.


Изображение для кнопки 3.

(. ) Обратите внимание, что у данных изображений прозрачный фон.

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

Теперь для установки изображений необходимо перейти в свойства картинки, после чего мы установим значение параметра ImageScaling равным none, чтобы изображение не масштабировалось. Теперь в параметре Image мы можем выбрать изображение для загрузки, как показано на рисунке 11.
Рисунок 11. Установка изображений на кнопки.
В процессе выбора откроется окно, показанное на рисунке 12.
Рисунок 12. Импорт рисунка для установки на кнопке.
Теперь щелкните на кнопке Import и выберите необходимый рисунок. Аналогично повторите с другими рисунками. В результате вы получите 3 красивые кнопки, как показано на рисунке 13.
Рисунок 13. Пример созданной панели инструментов.
Для того чтобы создать обработчики нажатий на кнопки этого ToolBox'а, достаточно совершить двойной щелчок мыши на каждом из них – MS Visual Studio автоматически сгенерирует код обработчик события и заготовки функций.

В будущем мы добавим вызов необходимых нам функций из этого обработчика.

Чтобы пользователь мог выбирать файл для загрузки через стандартное в Windows окно загрузки файлов, мы выполним следующие действия.
Перейдите к окну ToolBox (Панель элементов).
Теперь перетащите элемент управления OpenFileDialog (рис. 15) на форму.
Рисунок 15. Добавление элемента OpenFileDialog.
Местоположение, куда вы перетащите элемент, неважно: он добавится в поле под окном, к другим специфическим объектам (рис. 16).
Рисунок 16. Элемент OpenFileDialog, расположенный под редактируемой формой.
Как видно из рисунка 16, к дополнительным элементам, уже установленным на наше окно (меню и ToolBox), добавился еще и элемент OpenFileDialog1.
Теперь мы реализуем код открытия окна выбора файла, с необходимыми нам параметрами.

Если вы еще не создали обработчики нажатия на кнопки загрузки и элементы меню, так же предназначенные для загрузки, сделайте это с помощью двойных щелчков по ним.
Код сгенерированных функций выглядит следующим образом:


Теперь напишем следующую функцию LoadImage.

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

Добавление и вызов дополнительного диалогового окна

Для этого перейдите к окну Solution Explorer (Обозреватель решений), после чего щелкните на названии проекта правой кнопкой мыши и в открывшемся контекстном меню выберите Add->Form, как показано на рисунке 18.
Рисунок 18. Добавление в проект нового диалогового окна.
В открывшемся окне введите названия класса, который будет отвечать за генерацию нашего вспомогательного окна – Preview.cs (рис. 19).
Рисунок 19. Установка названия создаваемой формы для нового диалогового окна.
Теперь измените размер окна так, как показано на рисунке 20. Затем на форме разместите элемент panel. Внутри элемента panel разместите элемент pictureBox, как показано на рисунке 20.
Рисунок 20. Размещение элементов panel и picturebox на созданном диалоговом окне.
Данное окно будет получать при загрузке в качестве параметра ссылку на наше загруженное изображение. Затем оно будет устанавливать границы элемента pictureBox равными размерам полученного изображения, после чего устанавливать его в элемент pictureBox.

Перейдите к свойствам элемента panel и установите значение параметра AutoScroll равное true. Теперь, в том случае, если размер изображения будет превышать размер элемента panel1, будут появляться вертикальная и горизонтальная полоса прокрутки, с помощью которых можно будет просмотреть изображение.

Теперь рассмотрим исходный код, необходимый для реализации данных возможностей.

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

Он будет выглядеть следующим образом:


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

Перейдите к окну Preview, после чего сделайте двойной щелчок левой клавшей мыши на нем (НЕ на размещенных на нем объектах).

Откроется для редактирования функция:


Но мы сначала изменим код конструктора класса, теперь он будет выглядеть следующим образом:


Теперь отредактируем код функции Preview_Load. Он будет выглядеть следующим образом:


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

В следующей главе мы познакомимся с методами создания многопоточных приложений на примере разработки двух приложений.

Меню, панели и строки состояния являются неотъемлемой частью большинства приложений. Без меню можно обойтись, если ваше приложение выполняет всего два-три действия, которые можно оформить просто в виде кнопок на поверхности главной формы. Даже в тех случаях, когда программа выполняет всего пару команд, программисты все же предпочитают внедрять в окно меню, потому что это, кроме всего прочего, еще и эстетично.

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

Компоненты, которые мы будем рассматривать далее, находятся в разделе Menus & Toolbars панели Toolbox, поэтому если не сказано другого, то ищите компонент именно в этом разделе.

5.9.1. MenuStrip

Начнем рассмотрение с собственно меню. Создайте новое приложение и поместите на его форму компонент MenuStrip. Вдоль верхней кромки окна под его заголовком будет растянута панель меню. У меня этот компонент получил название menuStrip1. Выделите форму и обратите внимание, что в свойстве MainMenuStrip появилось имя нашего компонента меню. Так как ни одного меню еще на форме не было, то дизайнер взял на себя смелость, а может быть, и наглость, назначить новый компонент в качестве главного меню формы.

Если выделить компонент, то слева появятся светлый прямоугольник и серая надпись внутри Type Here (Напечатайте здесь). Если щелкнуть по этому прямоугольнику, то в нем появится маленькое поле ввода, в которое можно ввести имя нового пункта меню. Введите Файл и нажмите клавишу . Обратите внимание, что теперь и снизу от нашего пункта меню и справа снова появились прямоугольники с надписью Type Here (рис. 5.22).

Щелкнув на прямоугольнике снизу, можно создать пункт подменю, а если щелкнуть справа, то можно создать еще один раздел меню. Так можно создавать структуру программного меню. Попробуйте навести мышь на прямоугольник, но не щелкать по нему. В прямоугольнике появится кнопка выпадающего списка, по нажатию на которую появится всплывающее меню с элементами, которые вы можете добавить в компонент меню. Здесь у нас есть возможность работать со следующими компонентами:

  • MenuItem — элемент меню, который создается по умолчанию;
  • ComboBox — выпадающий список. Да, вы можете добавлять в качестве элементов меню даже выпадающий список, хотя это делается очень редко;
  • Separator — полоса, которая разделяет подменю на группы. Тут нужно сделать акцент на подменю, потому что разделитель невозможно создать для основных разделов меню;
  • TextBox — поле ввода тоже может быть внедрено прямо в меню.


Рис. 5.22. Редактор меню

Если щелкнуть по любому пункту меню двойным щелчком, то дизайнер создаст обработчик события по умолчанию, — т. е. событие Click. Это действие равносильно выделению пункта меню в дизайнере, переходу на вкладку событий в панели свойств и созданию обработчика для события Click.

Давайте создадим меню Выход, щелкнем по нему двойным щелчком и в созданном обработчике события напишем вызов метода Close():

Метод Close() формы приводит к закрытию окна. Если это главное окно приложения, то по его закрытию прерывается и главный обработчик событий (он создается приложением незаметно для нас), что приведет к завершению работы приложения.

Что интересного есть у пунктов меню? Во-первых, нужно понимать, что они происходят от класса ToolStripMenuItem и наследуют его свойства и методы. Наиболее интересные свойства следующие:

  • Checked — булево значение, которое указывает, поставлен ли флажок Check у меню. Если меню отмечено, то слева от имени появляется флажок, как у CheckBox;
  • CheckOnClick — это свойство указывает на то, что при выборе меню значение параметра Checked будет меняться на противоположное;
  • CheckState — идентично по назначению с одноименным свойством у CheckBox;
  • DisplayStyle — стиль отображения пункта меню. Здесь можно выбрать одно из значений:
    • ImageAndText — картинка и текст;
    • Image — картинка;
    • Text — текст;
    • None — ничего;

    Для всех пунктов меню, в том числе и контекстных, которые мы будем рассматривать в разд. 5.9.2, самым интересным событием, конечно же, является Click, которое возникает, когда пользователь щелкнул по элементу меню. Помимо этого вам могут пригодиться события CheckedChanged и CheckStateChanged, которые возникают, когда пользователь поставил флажок (изменил свойство Changed) или изменил свойство CheckState соответственно.

    5.9.2. ContextMenuStrip

    Попробуйте выделить какой-то элемент управления на форме или саму форму, и с формы исчезнет не только редактор контекстного меню, но и само контекстное меню. Это потому, что оно не визуально. Невизуальные компоненты появляются на специальной панели под формой (рис. 5.23). Чтобы снова отобразить визуальный редактор меню, нужно выделить соответствующий компонент контекстного меню на специальной панели.


    Рис. 5.23. Контекстное меню

    Создание контекстного меню идентично созданию пунктов главного меню. Создаются элементы одного и того же класса — ToolStripMenuItem, поэтому нет смысла повторяться и снова рассматривать его свойства.

    Как теперь использовать контекстное меню? Выделите компонент или форму, которой вы хотите назначить меню. Найдите свойство ContextMenuStrip и выделите его. Щелкните по появившейся кнопке вызова выпадающего списка в редакторе свойств, и в нем вы увидите имя созданного компонента контекстного меню. Выберите его. Больше ничего делать не нужно. Можете запустить приложение, щелкнуть правой кнопкой по компоненту или форме и убедиться, что контекстное меню появляется.

    5.9.3. ToolStrip

    Панели ToolStrip чаще всего дублируют функции, которые уже есть в меню, предоставляя пользователю возможность быстро вызвать команду. Для удобного создания меню лучше всего использовать компонент класса ToolStrip.

    Создайте новое приложение и перетащите на него компонент ToolStrip. Этот компонент по умолчанию будет растянут вдоль верхнего края окна. Когда панель выделена в редакторе, то слева появляется специализированная кнопка, которая существует виртуально и содержит небольшую стрелку для вызова выпадающего меню (рис. 5.24).


    Рис. 5.24. Редактор панели

    При щелчке по самой виртуальной кнопке будет создана кнопка класса ToolStripButton на поверхности панели. Если вызвать выпадающее меню, то в нем можно выбрать тип создаваемого компонента на поверхности панели. Вы можете создать следующие типы компонентов:

    • Button — кнопка;
    • Label — метка;
    • SplitButton — кнопка, которая имеет дополнительную кнопку для вызова всплывающего меню. Основная и дополнительная кнопки работают независимо;
    • DropDownButton — кнопка, которая вызывает всплывающее меню. Всплывающее меню появится именно по нажатию кнопки, без нажатия каких-либо дополнительных кнопок;
    • Separator — разделитель, который позволяет логически разделять группы кнопок;
    • ComboBox — выпадающий список;
    • TextBox — текстовое поле ввода;
    • ProgressBar — индикатор процесса.

    Создаваемая кнопка ToolStripButton (кнопки такого класса создаются на панели ToolStrip) очень схожа по свойствам с кнопкой Button, которую мы уже рассматривали, только у нее есть свойства Checked, CheckOnClick и CheckState, как у пункта меню и у компонента CheckBox, чтобы кнопку можно было не просто нажимать, но и изменять состояние — утапливать и отпускать. Когда свойство CheckOnClick равно true, то при нажатии кнопка залипает, меняя состояние Checked на true, а при повторном нажатии кнопка отпускается, меняя Checked на false. В противном случае при нажатии кнопка нажимается и тут же отпускается.

    Остальные компоненты, которые вы можете создать на поверхности панели, идентичны похожим компонентам, которые мы рассматривали ранее. Например, SplitButton и DropDownButton похожи по свойствам на классическую кнопку, просто у них есть дополнительная возможность в виде жестко привязанного меню, и при выделении кнопки в редакторе появляется редактор для этого меню.

    Компоненты ComboBox, TextBox и ProgressBar идентичны стандартным компонентам, которые мы рассматривали в разд. 5.7.

    5.9.4. StatusStrip

    Строка состояния, как следует из названия, предназначена для того, чтобы отображать состояние работы программы. Строка состояния (StatusStrip) сама по себе ничего особого собой не представляет. Самое интересное находится внутри этого компонента, на поверхности которого вы можете создавать компоненты, которые и будут выполнять какую-то функцию. Например, компонент типа метки может отображать текстовую информацию.

    Когда компонент строки состояния выделен, то слева появляется небольшая кнопка, по нажатию на которую создается метка класса ToolStripStatusLabel, похожая на метку Label и также предназначенная для отображения информации. Если нужно создать компонент другого класса, то можно маленькой кнопкой со стрелкой вызвать всплывающее меню, в котором имеются дополнительные элементы:

    • StatusLabel — метка;
    • ProgressBar — индикатор процесса;
    • SplitButton — кнопка, которая имеет дополнительную кнопку для вызова всплывающего меню. Основная и дополнительная кнопки работают независимо;
    • DropDownButton — кнопка, которая вызывает всплывающее меню. Всплывающее меню появится именно по нажатию кнопки, без нажатия на какие-либо дополнительные кнопки.

    Мой вопрос: есть ли способ сделать это, может быть, какое-то секретное свойство кнопки, которое позволяет прикрепить к нему меню?

    Любая помощь будет оценена.

    ОТВЕТЫ

    Ответ 1

    Вы можете показать ContextMenuStrip в событии click:

    Чтобы сделать свое собственное определение, показывать ли меню выше или ниже кнопки, вы можете попробовать использовать этот код, который измеряет меню и определяет, будет ли он частично вне экрана:

    Ответ 2

    Кнопка имеет стрелку вниз справа от нее, и вы можете выбрать меню из конструктора:

    ss

    ss

    Ответ 3

    Развертывание @Jaex немного ответит, чтобы учесть разделительную линию, условное рисование стрелки, если ничего не настроено, и отдельное событие щелчка для основного тела кнопки и стрелки меню.

    Следует отметить, что для лучшего выравнивания вы можете установить button.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;

    enter image description here

    Вот мое небольшое улучшение

    Ответ 4

    Легко мы могли это сделать. это может помочь:)

    Ответ 5

    Самый простой вариант - использовать ToolStripDropDownButton в незакрепленном ToolStrip, который отображает только одну кнопку. Затем вы можете добавить к нему подпозиции и т.д. Чтобы сделать это: - перетащите панель инструментов на свой элемент управления/форму - используйте помощник компоновки, чтобы добавить DropDownButton - установить GripStyle в скрытое - установить Dock в None

    В результате создается отдельная кнопка в стиле панели инструментов, которая поддерживает описанное выше раскрывающееся поведение.

    Ответ 6

    Показывать контекстное меню под кнопкой при нажатии.

    Ответ 7

    Класс Jaex MenuButton выше был идеален для меня. Я добавил логику ниже в OnMouseDown, чтобы контекстное меню отображалось только в том случае, если я нажал на стрелку. Если щелкнуть по большей части, произойдет обычное событие щелчка. Разрешено действие щелчка по умолчанию.

    Думал, что это может быть полезно кому-то. Спасибо Jaex

    Ответ 8

    Таким образом, он определенно существует, однако вы не можете искать платный сторонний элемент управления.

    Ответ 9

    Я тоже занимался этой проблемой и нашел очень простое решение (хотя и немного грязно-взломанное): поместите ComboBox под Button , чтобы он показывал стрелку вниз рядом с кнопкой.

    Затем используйте SelectedIndexChanged для ComboBox , чтобы изменить поведение Button или сделать то, что вы хотите сделать немедленно.

    Создадим Windows Application решение, как показано в параграфе "Простейшие Windows Application решения", и поместим на форму контрол MenuStrip. Он разместится внизу окна редактора формы.

    В функции InitialiseComponent() файла Form1.Designer.cs, как и при добавлении других контролов, появятся строки определения меню и задания его свойств:

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

    LayoutStyle - расположение пунктов меню на форме, выберем HorisontalStackWithOverflow (по умолчанию);

    MaximumSize и MiniumSize, Size - иногда бывает целесообразно выбрать размер по Y, такой, чтобы можно было разместить рисунки на панели меню без их искажения (зависит от конкретной ситуации).

    BackColor - по своему усмотрению или можно выбрать значение Control (цвет, в данном случае, формы).

    Остальные параметры оставим без изменения.

    Далее, будем добавлять пункты меню. Прежде всего можно добавить стандартный набор пунктов меню, если кликнуть мышкой на маленькой стрелочке в правом верхнем углу панели меню и выбрать ссылку Insert Standart Items (Рис.1.).

    Рис.1. Добавление стандартных пунктов меню

    Окно MenuStript Tasks дает еще несколько возможностей по конструированию меню, в том числе задать расположение меню, включить пункты меню в контейнер, быстро перейти к редактированию пунктов меню. Однако, далее мы создадим несколько пунктов меню, обычным образом. Для этого, кликнем мышкой на панели меню в дизайнере формы. На образце формы появилась полоска с окошечком "Type Here". Введем традиционый для всех меню пункт &File - окно "Type Here" размножилось, показывая направления дальнейшего ввода (Рис.2.), а в окне редактора кода в определениях и функции InitializeComponent() добавился код:

    Рис.2. Добавление и редактирование пунктов меню

    Далее, вводим в "Type Here" подпункт "Exit" (Рис.2.). После чего, для данного пункта, в его контекстном меню, выбираем Properties. И, прежде всего, задаем горячую клавишу, выбрав свойство ShortcutKeys, как показано на Рис.3.

    Рис.3. Задание горячих клавиш

    Для данного пункта создаем обработчик события выбора подпункта меню Exit. Как и для кнопок, можно создать обработчик двойным кликом мышки на данном пункте в дизайнере формы или в меню Properties на вкладке Events двойным кликом мышки в окне свойства Click.

    Соответственно в файле Form1.Designer.cs добавился код:

    Далее нажимаем F5 и можем пользоваться меню формы File | Exit или горячими клавишами Alt+X для закрытия формы.

    Параграф 2. Особенности создания контекстного меню

    Контекстное меню создается, во многом, аналогично меню формы.

    Рис.4. Создание и подключение контекстного меню для формы

    Как видно из Рис.4., для создания контекстного меню, необходимо поместить на форму контрол СontextMenuStrip. Далее, полная аналогия с созданием меню формы (разработчики даже ввод имен пунктов меню поместили в тоже место формы, где добавляются пункты меню формы, в ее верхнюю часть). Задание обработчиков (событие Click) также можно выполнить двойным кликом на пункте меню или на вкладке Events окна Properties контрола, где могут быть заданы и другие обработчики.

    Однако контекстное меню, в отличие от меню формы, требует подключения. Для этого в окне Proporties для формы (или любого другого контрола, который имеет свойство ContextMenu) в выпадающем списке ContextMenu должно быть выбрано созданное контекстное меню.

    Читайте также: