Сделать владельцем рисованные меню в C#
Проще всего использовать меню со стандартным внешним видом, но вы можете сделать владельцы рисованных меню, если хотите. Это не сложно, но вам нужно выполнить несколько шагов.
Сначала во время разработки установите для элемента OwnerDraw элемент управления MenuItem значение true. Затем во время выполнения вы должны ответить на два события для меню: MeasureItem и DrawItem.
Обработчик событий MeasureItem получает в качестве параметра объект типа MeasureItemEventArgs. Код должен устанавливать свойства объекта ItemHeight и ItemWidth этого объекта, чтобы сообщить программе, сколько места требуется для пункта меню.
В этом примере используется следующий код, чтобы определить, насколько велика будет его строка. Затем он запрашивает достаточно места для строки.
private const string FONT_NAME = "Times New Roman"; private const float FONT_SIZE = 12; private const FontStyle FONT_STYLE = FontStyle.Bold; private const string MENU_CAPTION = "Say Hi"; // Скажите Windows, как большой элемент меню. private void mnuFileSayHi_MeasureItem( object sender, MeasureItemEventArgs e) { // Создаем шрифт, который мы будем использовать для рисования текста. using (Font menu_font = new Font( FONT_NAME, FONT_SIZE, FONT_STYLE)) { // Посмотрим, насколько большой будет текст. SizeF text_size = e.Graphics.MeasureString(MENU_CAPTION, menu_font); // Установите необходимый размер. e.ItemHeight = (int)text_size.Height; e.ItemWidth = (int)text_size.Width; } }
Этот код начинается с некоторых констант, которые определяют шрифт, который программа будет использовать для рисования элемента меню. Обработчик события MeasureItem создает шрифт и использует e.Graphics.MeasureString, чтобы узнать, сколько пространства требуется в этом шрифте для текста. Затем он устанавливает e.ItemHeight и e.ItemWidth соответственно.
Обработчик события DrawItem получает в качестве параметра объект типа DrawItemEventArgs, который имеет свойства и методы, которые позволяют нарисовать элемент меню. Следующий код показывает обработчик события DrawItem в программе примера
.
// Нарисуем элемент меню. private void mnuFileSayHi_DrawItem( object sender, DrawItemEventArgs e) { // Создаем шрифт, который мы будем использовать для рисования текста. using (Font menu_font = new Font( FONT_NAME, FONT_SIZE, FONT_STYLE)) { // Смотрите, находится ли мышь над элементом меню. if ((e.State & DrawItemState.Selected) != DrawItemState.None) { // Мышь над элементом. // Рисуем затененный фон. using (Brush menu_brush = new LinearGradientBrush( e.Bounds, Color.Red,Color.Black,90)) { e.Graphics.FillRectangle(menu_brush, e.Bounds); } // Рисуем текст. e.Graphics.DrawString(MENU_CAPTION, menu_font, System.Drawing.Brushes.AliceBlue, e.Bounds.X, e.Bounds.Y); } else { // Мышь не над элементом. // Стереть фон. e.Graphics.FillRectangle( System.Drawing.Brushes.LightGray, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height); // Рисуем текст. e.Graphics.DrawString(MENU_CAPTION, menu_font, System.Drawing.Brushes.Black, e.Bounds.X, e.Bounds.Y); } } }
Обработчик события создает шрифт, а затем проверяет e.State, чтобы увидеть, находится ли мышь над пунктом меню. Если это так, программа рисует фон градиента и текст меню в AliceBlue. Если мышь не находится над пунктом меню, программа рисует простой светло-серый фон с черным текстом.
Этот пример просто рисует текст с фоном, но вы можете рисовать изображения, фигуры или что-то еще, что вы хотите отображать в меню.
Значение e.State может указывать другие свойства элемента меню. Например, он может сказать вам, если элемент отключен, отмечен или находится в его визуальном состоянии по умолчанию. Вы можете изменить способ, которым вы рисуете элемент, если хотите.