Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование
Скачать 5.54 Mb.
|
449 кнопки (команда btn.Text=name в теле метода) и текстовое значение file , определяющее название файла с изображением животного. При выполнении команды pict.Image=Image.FromFile(path+file) в теле метода на основе указанного файла создается объект изображения, и это изображение применяется для метки. Объект ts для панели инструментов создается на основе класса ToolStrip командой ToolStrip ts=new ToolStrip(). Для кнопок, которые предполагается размещать на панели инструментов, создаются объекты. Объекты создаются на основе класса ToolStripButton. Аргументом конструктору класса передается ссылка на объект изображения, которое применяется для кнопки. Всплывающие подсказки для кнопки на панели инструментов задаем, присвоив текстовое значение свойству ToolTipText объекта кнопки. Обработку событий, связанных со щелчком по кнопкам на панели инструментов, мы реализуем следующим образом при щелчке по кнопке происходит программное генерирование события, связанного с выбором соответствующей команды изменю. Для этого в список обработчиков события Click объекта кнопки добавляется анонимный метод, определяемый лямбда-выражением. В теле лямбда-выражения использован метод PerformClick(), выполнение которого означает программный щелчок по команде изменю (метод вызывается из объекта этой команды. Для добавления кнопок на панель инструментов из свойства Items ссылка на коллекцию элементов панели меню) объекта панели вызывается метод Add(). Ссылка на объект добавляемой кнопки указывается аргументом метода. Наконец, командой this.Controls.Add(ts) панель инструментов добавляется в окно. Также в конструкторе создается объект метки, задаются ее размеры, положение и тип рамки. Метка добавляется в окно. Также создается кнопка. Определяются ее размеры, положение, шрифта в качестве обработчика регистрируется метод OnButtonClick(). После добавления кнопки в окно выполняется команда wolf. PerformClick() , означающая программный щелчок на команде Волк. В результате для метки применяется изображение с волком, а также название Волк получает кнопка. В главном методе программы командой Application.Run(new MyForm()) отображается окно, описанное в самом начале раздела Глава Контекстное меню Плюк — чатланская планета, поэтому мы, па- цаки, должны цаки носить. из к/ф «Кин-дза-дза» Далее мы познакомимся с контекстным меню. Это меню, которое открывается при щелчке правой кнопкой мыши на компоненте. В следующей программе создается и отображается окно традиционно с изображением животного. Окно представлено на рис. Рис. 8.33. При первом отображении окна оно содержит изображение волка, флажок опции установлена поле ввода заблокировано В центральной части окна сначала появляется изображение волка. Если щелкнуть правой кнопкой мыши на изображении, появляется контекстное меню из четырех команд, названия которых совпадают с названиями животных. Ситуация проиллюстрирована на рис. Рис. 8.34. Выбор команды в контекстном меню изображения Приложения с графическим интерфейсом 451 Выбрав команду в контекстном меню, мы меняем изображение в окне. Одновременно с изображением меняется и заголовок окна. На рис. 8.35 показан результат, который получим при выборе команды Лиса в контекстном меню. Рис. 8.35. В результате выбора команды в контекстном меню меняется изображение и заголовок окна Кроме изображения, в окне под изображением есть опция Заблокировать поле и поле ввода над изображением. При установленном флажке опции поле заблокировано (выделено серым цветом и недоступно для ввода. Если отменить флажок для опции, тов поле можно вводить текст, как показано на рис. Рис. 8.36. Пока в поле ввода не указано корректное название животного, изображение в окне не меняется Как только в поле ввода будет введено название животного (Волк, Лиса, Медведь или Енот, в окне изменится изображение животного и заголовок окна. На рис. 8.37 показано, как выглядит окно, если в текстовое поле ввести слово ȿɧɨɬ. Глава Рис. 8.37. При вводе в текстовое поле корректного названия животного, его изображение появляется в окне Если установить флажок опции, тополе снова станет неактивным, а текст из поля будет удален. Как и ранее, мы можем выбрать команду из контекстного меню. На рис. 8.38 показано, как при активном текстовом поле в контекстном меню выбирается команда Медведь. Рис. 8.38. Выбор команды из контекстного меню при активном поле ввода В результате в окне появляется изображение медведя, меняется заголовок окна, у опции появляется флажок, из поля удаляется текст, и поле блокируется. Как будет выглядеть окно в этом случае, показано на рис. Рис. 8.39. После выбора команды из контекстного меню меняется изображение и заголовок окна, устанавливается флажок опции и блокируется поле ввода Приложения с графическим интерфейсом 453 Далее мы проанализируем программный код программы, который представлен в листинге Листинг 8.9. Контекстное меню System; using System.Drawing; using System.Windows.Forms; // Ʉɥɚɫɫ ɨɤɧɚ: class MyForm:Form{ // ɋɫɵɥɤɚ ɧɚ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ: private TextBox tb; // ɋɫɵɥɤɚ ɧɚ ɦɟɬɤɭ: private Label lbl; // Ɂɚɤɪɵɬɵɣ ɦɟɬɨɞ ɞɥɹ ɩɪɨɜɟɪɤɢ ɧɚɡɜɚɧɢɹ ɠɢɜɨɬɧɨɝɨ: private bool checkIt(string name){ switch(name){ case ƎȼɨɥɤƎ: case ƎɅɢɫɚƎ: case ƎɆɟɞɜɟɞɶƎ: case ƎȿɧɨɬƎ: return true; default: return false; } } // Ɂɚɤɪɵɬɵɣ ɦɟɬɨɞ ɞɥɹ ɨɩɪɟɞɟɥɟɧɢɹ ɩɨ ɧɚɡɜɚɧɢɸ ɠɢɜɨɬɧɨɝɨ // ɧɚɡɜɚɧɢɹ ɮɚɣɥɚ ɫ ɢɡɨɛɪɚɠɟɧɢɟɦ: private string getFile(string name){ string path= ƎD:/Books/pictures/csharp/Ǝ; string res= ƎƎ; switch(name){ case ƎȼɨɥɤƎ: Глава 8 454 res= Ǝwolf.jpgƎ; break; case ƎɅɢɫɚƎ: res= Ǝfox.jpgƎ; break; case ƎɆɟɞɜɟɞɶƎ: res= Ǝbear.jpgƎ; break; case ƎȿɧɨɬƎ: res= Ǝraccoon.jpgƎ; break; } return path+res; } // Ʉɨɧɫɬɪɭɤɬɨɪ: public MyForm():base(){ // Ʌɨɤɚɥɶɧɵɟ ɩɟɪɟɦɟɧɧɵɟ: int H=104; int W=154; // Ɋɚɡɦɟɪɵ ɨɤɧɚ: this.Width=W+25; this.Height=240; // ɒɪɢɮɬ ɞɥɹ ɨɤɧɚ: this.Font=new Font( ƎArialƎ,9,FontStyle.Bold); // Ɉɤɧɨ ɩɨɫɬɨɹɧɧɵɯ ɪɚɡɦɟɪɨɜ: this.FormBorderStyle=FormBorderStyle.FixedToolWindow; // ɇɚɱɚɥɶɧɨɟ ɩɨɥɨɠɟɧɢɟ ɨɤɧɚ: this.StartPosition=FormStartPosition.CenterScreen; // Ɉɛɴɟɤɬ ɬɟɤɫɬɨɜɨɝɨ ɩɨɥɹ: tb=new TextBox(); // ɉɨɥɨɠɟɧɢɟ ɬɟɤɫɬɨɜɨɝɨ ɩɨɥɹ: tb.Location=new Point(5,5); Приложения с графическим интерфейсом // ɒɢɪɢɧɚ ɬɟɤɫɬɨɜɨɝɨ ɩɨɥɹ: tb.Width=W; // ɒɪɢɮɬ ɞɥɹ ɬɟɤɫɬɨɜɨɝɨ ɩɨɥɹ: tb.Font=new Font( ƎCourier NewƎ,12,FontStyle.Bold); // Ɉɛɪɚɛɨɬɱɢɤ ɫɨɛɵɬɢɹ, ɫɜɹɡɚɧɧɨɝɨ ɫ ɨɬɩɭɫɤɚɧɢɟɦ // ɤɥɚɜɢɲɢ ɧɚ ɤɥɚɜɢɚɬɭɪɟ: tb.KeyUp+=(x,y)=>{ // ȿɫɥɢ ɜ ɩɨɥɟ ɧɚɡɜɚɧɢɟ ɠɢɜɨɬɧɨɝɨ: if(checkIt(tb.Text)){ // Ɂɚɝɨɥɨɜɨɤ ɨɤɧɚ: this.Text=tb.Text; // ɂɡɨɛɪɚɠɟɧɢɟ ɞɥɹ ɦɟɬɤɢ: lbl.Image=Image.FromFile(getFile(tb.Text)); } }; // Ⱦɨɛɚɜɥɟɧɢɟ ɩɨɥɹ ɜ ɨɤɧɨ: this.Controls.Add(tb); // Ɉɛɴɟɤɬ ɦɟɬɤɢ: lbl=new Label(); // ɉɨɥɨɠɟɧɢɟ ɢ ɪɚɡɦɟɪɵ ɦɟɬɤɢ: lbl.Top=tb.Bottom+5; lbl.Left=5; lbl.Size=new Size(W,H); // Ɋɚɦɤɚ ɞɥɹ ɦɟɬɤɢ: lbl.BorderStyle=BorderStyle.FixedSingle; // Ⱦɨɛɚɜɥɟɧɢɟ ɦɟɬɤɢ ɜ ɨɤɧɨ: this.Controls.Add(lbl); // Ɉɛɴɟɤɬ ɨɩɰɢɢ: CheckBox option=new CheckBox(); // Ɋɚɡɦɟɪɵ ɢ ɩɨɥɨɠɟɧɢɟ ɨɩɰɢɢ: option.Width=W; option.Height=20; Глава 8 456 option.Left=5; option.Top=lbl.Bottom+5; // ɉɨɞɩɢɫɶ ɞɥɹ ɨɩɰɢɢ: option.Text= ƎɁɚɛɥɨɤɢɪɨɜɚɬɶ ɩɨɥɟƎ; // Ɉɛɪɚɛɨɬɱɢɤ ɞɥɹ ɫɨɛɵɬɢɹ, ɫɜɹɡɚɧɧɨɝɨ ɫ ɢɡɦɟɧɟɧɢɟɦ // ɫɨɫɬɨɹɧɢɹ ɨɩɰɢɢ: option.CheckedChanged+=(x,y)=>{ // Ⱦɨɫɬɭɩɧɨɫɬɶ ɩɨɥɹ ɞɥɹ ɜɜɨɞɚ ɬɟɤɫɬɚ: tb.Enabled=!option.Checked; // Ɉɱɢɫɬɤɚ ɫɨɞɟɪɠɢɦɨɝɨ ɩɨɥɹ: tb.Text= ƎƎ; }; // Ⱦɨɛɚɜɥɟɧɢɟ ɨɩɰɢɢ ɜ ɨɤɧɨ: this.Controls.Add(option); // Ɉɛɴɟɤɬ ɤɨɧɬɟɤɫɬɧɨɝɨ ɦɟɧɸ: ContextMenuStrip menu=new ContextMenuStrip(); // Ⱦɨɛɚɜɥɟɧɢɟ ɤɨɦɚɧɞ ɜ ɤɨɧɬɟɤɫɬɧɨɟ ɦɟɧɸ: menu.Items.Add( ƎȼɨɥɤƎ); menu.Items.Add( ƎɅɢɫɚƎ); menu.Items.Add( ƎɆɟɞɜɟɞɶƎ); menu.Items.Add( ƎȿɧɨɬƎ); // ɉɟɪɟɛɨɪ ɷɥɟɦɟɧɬɨɜ ɢɡ ɤɨɧɬɟɤɫɬɧɨɝɨ ɦɟɧɸ: for(int k=0;k Ɉɛɪɚɛɨɬɱɢɤ ɞɥɹ ɤɨɦɚɧɞɵ ɢɡ ɤɨɧɬɟɤɫɬɧɨɝɨ ɦɟɧɸ: menu.Items[k].Click+=(x,y)=>{ // ɇɚɡɜɚɧɢɟ ɤɨɦɚɧɞɵ: string txt=((ToolStripMenuItem)x).Text; // ɂɡɨɛɪɚɠɟɧɢɟ ɞɥɹ ɦɟɬɤɢ: lbl.Image=Image.FromFile(getFile(txt)); // Ɂɚɝɨɥɨɜɨɤ ɨɤɧɚ: this.Text=txt; // ɍɫɬɚɧɚɜɥɢɜɚɟɬɫɹ ɮɥɚɠɨɤ ɨɩɰɢɢ: Приложения с графическим интерфейсом option.Checked=true; }; } // Ʉɨɧɬɟɤɫɬɧɨɟ ɦɟɧɸ ɞɥɹ ɦɟɬɤɢ: lbl.ContextMenuStrip=menu; // Ɉɛɴɟɤɬ ɤɧɨɩɤɢ: Button btn=new Button(); // ɇɚɡɜɚɧɢɟ ɤɧɨɩɤɢ: btn.Text= ƎOKƎ; // ɉɨɥɨɠɟɧɢɟ ɢ ɪɚɡɦɟɪɵ ɤɧɨɩɤɢ: btn.SetBounds(5,option.Bottom+5,W,30); // Ɉɛɪɚɛɨɬɱɢɤ ɞɥɹ ɫɨɛɵɬɢɹ, ɫɜɹɡɚɧɧɨɝɨ ɫɨ ɳɟɥɱɤɨɦ // ɩɨ ɤɧɨɩɤɟ: btn.Click+=(x,y)=>{ Application.Exit(); }; // Ⱦɨɛɚɜɥɟɧɢɟ ɤɧɨɩɤɢ ɜ ɨɤɧɨ: this.Controls.Add(btn); // ɉɪɨɝɪɚɦɦɧɵɣ ɳɟɥɱɨɤ ɧɚ ɩɟɪɜɨɣ ɤɨɦɚɧɞɟ // ɢɡ ɤɨɧɬɟɤɫɬɧɨɝɨ ɦɟɧɸ: menu.Items[0].PerformClick(); } } // Ƚɥɚɜɧɵɣ ɤɥɚɫɫ: class ContextMenuDemo{ [STAThread] // Ƚɥɚɜɧɵɣ ɦɟɬɨɞ: static void Main(){ // Ɉɬɨɛɪɚɠɟɧɢɟ ɨɤɧɚ ɫ ɩɨɥɟɦ ɜɜɨɞɚ: Application.Run(new MyForm()); } } Глава В классе окна MyForm есть закрытое поле tb класса TextBox (ссылка на текстовое поле) и закрытое поле lbl класса Label (ссылка наметку. Также в классе описан закрытый метод checkIt(), аргументом которому передается текстовое значение, а результатом метод возвращает логическое значение true или false в зависимости оттого, является ли переданный текст названием животного или нет (допускаются варианты ƎȼɨɥɤƎ, ƎɅɢɫɚƎ, ƎɆɟɞɜɟɞɶƎ и В классе есть закрытый метод getFile() для определения по названию животного (аргумент метода) названия файла с изображением (результат метода. Причем возвращается текст с полным путем к файлу НАЗ А МЕТКУ Если аргументом методу getFile() передать текст, который не является названием животного (имеются ввиду названия " ȼɨɥɤ" , " Ʌɢɫɚ" , " Ɇɟɞɜɟɞɶ" или " ȿɧɨɬ" ), то результатом метод возвращает текстовую строку с путем к каталогу с файлами изображений. Но поскольку в программе этот метод вызывается только в случае, если аргумент является названием животного, то проблем не возникает. В конструкторе класса задаются размеры и начальное положение окна, шрифт для окна, а также командой this.FormBorderStyle= FormBorderStyle.FixedToolWindow определяется тип окна. Это окно постоянных размеров без пиктограмм минимизации и максимиза- ции окна (в правом верхнем углу есть только одна системная пиктограмма для закрытия окна). Также в конструкторе создается объект для текстового поля. Определяется положение поля и его ширина, задается шрифт для поля (высота поля автоматически определяется на основе шрифта. Для поля регистрируется обработчик события, связанного с отпусканием клавиши на клавиатуре (событие происходит, если поле активно и пользователь отпускает ранее нажатую клавишу. Для этого в список обработчиков события KeyUp объекта поля tb добавляется ссылка на анонимный метод, реализованный с помощью лямбда-выражения. В теле метода в условном операторе проверяется условие checkIt(tb.Text). Условие истинно, если в текстовом поле содержится название животного. Если так, то командой this.Text=tb.Text содержимое текстового поля становится заголовком окна. Затем командой lbl.Image=Image. FromFile(getFile(tb.Text)) определяется изображение для Приложения с графическим интерфейсом 459 метки. В этом случае по названию животного в текстовом поле определяется название файла с изображением (инструкция getFile(tb. Text) ), и оно передается аргументом методу Помимо перечисленного выше, в конструкторе создается метка, определяются ее параметры, а также создается опция. Для опции определяется обработчик события, связанного с изменением состояния опции в список обработчиков для события CheckedChanged объекта опции option добавляется ссылка на анонимный метод, реализованный с помощью лямб- да-выражения. В теле метода командой tb.Enabled=!option.Checked определяется значение свойства Enabled текстового поля. Если значение свойства равно true, тополе доступно для ввода текста. Если значение свойства равно false, тополе заблокировано. В данном случае значение свойства Enabled противоположно значению свойства Checked опции НАЗ А МЕТКУ То есть если опция установлена, тополе заблокировано, а если опция не установлена, тополе доступно для редактирования. Также командой tb.Text= ƎƎ содержимое поля «обнуляется»: в поле записывается пустой текст. Для контекстного меню на основе класса ContextMenuStrip создается объект menu. Для добавления команд в контекстное меню из свойства Items объекта меню вызывается метод Add(), аргументом которому передается текст с названием команды. Для каждой команды определяется обработчик события, связанного со щелчком на команде меню. Для перебора элементов (команд) из контекстного меню используем оператор цикла. Команды контекстного меню образуют коллекцию, ссылку на которую получаем с помощью свойства Items объекта меню menu. У свойства Items есть свойство Count, возвращающее в качестве значения количество элементов (команд) в коллекции. В операторе цикла индексная переменная k пробегает значения индексов элементов в коллекции. На каждой итерации цикла в список обработчиков события Click элемента Items[k] добавляется ссылка на анонимный метод, реализованный с помощью лямбда-выражения. В лямбда-выражении командой string txt=((ToolStripMenuItem)x).Text в текстовую переменную записывается название команды, на которой произошло событие (на которой был выполнен щелчок Глава 8 460 q ПОДРОБНО СТ ИВ лямбда-выражении первый аргумент (обозначен как x ) обозначает объект компонента, на котором произошло событие. В соответствии с определением делегата EventHandler этот аргумент относится к классу object . Мы знаем, что этот объект — команда контекстного меню. Поэтому объект приводится к типу ToolStripMenuItem инструкция. Свойство Text этого объекта — это название команды, что нами нужно. Командой lbl.Image=Image.FromFile(getFile(txt)) задается изображение для метки. Заголовок окна определяем командой this. Text=txt . С помощью команды option.Checked=true устанавливается флажок опции (при этом выполняется обработка события, связанного с изменением статуса опции. Чтобы созданное меню стало контекстным меню метки с изображением, используем команду lbl. ContextMenuStrip=menu (свойству ContextMenuStrip в качестве значения присваивается ссылка на объект контекстного меню). Также мы создаем объект кнопки, задаем ее параметры и определяем обработчик события, связанного со щелчком по кнопке. Компоненты поле, метка, опция и кнопка) добавляются в окно, после чего командой) выполняется программный щелчок на первой команде из контекстного меню. В результате в окне появляется изображение волка и выполняются прочие сопутствующие настройки. В главном методе создается и отображается окно. Координаты курсора мыши Меня не интересуют ваши координаты. Беда догоняет регату, скоро финиш. Товар не должен вернуться назад. из м/ф Приключения капитана Врунгеля» Еще один пример, который мы рассмотрим в этой главе, связан с использованием параметров курсора мыши. Кроме этого, мы увидим, как можно выполнять рисование в области графического компонента. Программа выполняется следующим образом. Вначале отображается окно с большой областью желтого цвета и меткой в верхней части окна. Как выглядит окно вначале выполнения программы, показано на рис. 8.40. Приложения с графическим интерфейсом 461 Рис. 8.40. При запуске программы отображается окно сметкой и большой желтой панелью в центре Если курсор мыши оказывается над желтой областью, то он приобретает вид ладони, а через точку размещения курсора проходят две толстые линии (горизонтальная и вертикальная) синего цвета. Также в метке отображаются координаты курсора в системе координат, связанной с желтой областью. Точка начала координат находится в левом верхнем углу области, координаты определяются в пикселях как расстояние по горизонтали и вертикали от точки начала координат до точки в области (для которой определяются координаты. Как выглядит окно при наведенном на желтую область курсоре мыши, показано на рис. Рис. 8.41. При наведении курсора на область панели отображаются две линии и координаты курсора Глава При перемещении курсора мыши в области автоматически меняются значения координат в метке над областью, а также автоматически, вслед за курсором, перемещаются синие линии. Ситуацию иллюстрирует рис. Рис. 8.42. При перемещении курсора над панелью синхронно изменяются значения координат курсора и расположение линий В общих чертах так функционирует интересующая нас программа. Теперь проанализируем код программы, представленный в листинге Листинг 8.10. Координаты курсора System; using System.Drawing; using System.Windows.Forms; // Ʉɥɚɫɫ ɨɤɧɚ: class MyForm:Form{ // ɋɫɵɥɤɚ ɧɚ ɨɛɴɟɤɬ ɞɥɹ ɪɢɫɨɜɚɧɢɹ: Pen p; // ɋɫɵɥɤɚ ɧɚ ɨɛɴɟɤɬ ɝɪɚɮɢɱɟɫɤɨɝɨ ɤɨɧɬɟɤɫɬɚ: Graphics g; // Ʉɨɧɫɬɪɭɤɬɨɪ: public MyForm():base(){ // Ɋɚɡɦɟɪɵ ɨɤɧɚ: Приложения с графическим интерфейсом this.Width=325; this.Height=380; // Ɉɤɧɨ ɮɢɤɫɢɪɨɜɚɧɧɵɯ ɪɚɡɦɟɪɨɜ: this.FormBorderStyle=FormBorderStyle.FixedToolWindow; // Ɂɚɝɨɥɨɜɨɤ ɨɤɧɚ: this.Text= ƎɄɨɨɪɞɢɧɚɬɵ ɤɭɪɫɨɪɚƎ; // Ɉɛɴɟɤɬ ɦɟɬɤɢ: Label lbl=new Label(); // Ɋɚɡɦɟɪɵ ɦɟɬɤɢ: lbl.Width=300; lbl.Height=30; // ɉɨɥɨɠɟɧɢɟ ɦɟɬɤɢ: lbl.Location=new Point(5,5); // Ɋɚɦɤɚ ɞɥɹ ɦɟɬɤɢ: lbl.BorderStyle=BorderStyle.Fixed3D; // ɒɪɢɮɬ ɞɥɹ ɦɟɬɤɢ: lbl.Font=new Font( ƎArialƎ,10,FontStyle.Bold); // ɋɩɨɫɨɛ ɜɵɪɚɜɧɢɜɚɧɢɹ ɬɟɤɫɬɚ ɜ ɦɟɬɤɟ: lbl.TextAlign=ContentAlignment.MiddleCenter; // Ⱦɨɛɚɜɥɟɧɢɟ ɦɟɬɤɢ ɜ ɨɤɧɨ: this.Controls.Add(lbl); // Ɉɛɴɟɤɬ ɩɚɧɟɥɢ: Panel pnl=new Panel(); // Ɋɚɡɦɟɪɵ ɩɚɧɟɥɢ: pnl.Width=lbl.Width; pnl.Height=300; // ɉɨɥɨɠɟɧɢɟ ɩɚɧɟɥɢ: pnl.Top=lbl.Bottom+5; pnl.Left=lbl.Left; // Ɋɚɦɤɚ ɞɥɹ ɩɚɧɟɥɢ: pnl.BorderStyle=BorderStyle.Fixed3D; // ɐɜɟɬ ɩɚɧɟɥɢ: Глава 8 |