Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Основы создания оконных приложенийСтр 1 из 9Следующая ⇒
Основы создания оконных приложений Элементы управления Как мы уже говорили, внешний вид (официально – визуальный интерфейс) оконного приложения основан на стандартном наборе элементов, которые можно размещать в окне (на форме) приложения. Существует несколько десятков видов таких элементов (их еще называют элементами управления, а по-английски – control). Каждый вид элементов управления реализован с помощью некоторого класса. Все классы элементов управления являются производными от класса Control. Класс Control и все классы элементов управления находятся в пространстве имен System.Windows.Forms. Наиболее популярными являются командные кнопки (класс Button), надписи или метки (класс Label) и поля ввода (класс TextBox). Программно управлять внешним видом элементов управления можно через соответствующие открытые свойства классов. Например, размер элемента управления можно узнать или изменить с помощью свойств Height (высота) и Width(ширина). Одной из важных составляющих Вашего умения создавать оконные приложения является знание этих многочисленных свойств. Усовершенствуем нашу программу. После запуска в окне программы должны размещаться две кнопки. Размеры и расположение элементов на форме показаны на следующем рисунке: Для реализации такого поведения текст программы следует изменить следующим образом: 01. using System; 02. using System.Windows.Forms; 03. using System.Drawing; 04. static class Program 05. { 06. static void Main() 07. { 08. int FormHeight=300; 09. int FormWidth=500; 10. Form f; 11. Button b1; 12. Button b2; 13. //создание и настройка формы 14. f = new Form(); 15. f.ClientSize = new Size(FormWidth, FormHeight); 16. //создание и настройка первой кнопки 17. b1 = new Button(); 18. b1.Left = FormWidth / 5; //расстояние левой грани кнопки от левой грани клиентской области формы 19. b1.Top = FormHeight / 3; //расстояние верхней грани кнопки от верхней грани клиентской области формы 20. b1.Width = FormWidth / 5; //ширина кнопки 21. b1.Height = FormHeight / 3; //высота кнопки 22. //создание и настройка второй кнопки 23. b2 = new Button(); 24. b2.Bounds = new Rectangle(3*FormWidth / 5, FormHeight / 3, FormWidth / 5, FormHeight / 3); 25. //добавление кнопок на форму 26. f.Controls.Add(b1); 27. f.Controls.Add(b2); 28. //запуск цикла обработки событий 29. Application.Run(f); 30. } 31. } Текст программы существенно вырос. Объясним все подробнее.
1. В программе используются классы из пространства имен System.Drawing. Поэтому не забудьте доавить в проект ссылку (reference) на это пространство имен и соответствующую директиву using в текст программы (стр.03). 2. Для удобства управления размерами в стр. 08 и 09 вводятся вспомогательные переменные FormHeight (высота формы) и FormWidth(ширина формы). Они определяют размер внутренней области окна (клиентской области), не включающей заголовок и рамку вокруг окна. 3. Программа должна обращаться к свойчтвам формы и кнопок. Поэтому для ссылки на эти объекты в стр. 10-12 описываются соответствующие переменные. 4. После создания объекта-формы в стр.14 ее клиентский размер задается с помощью свойства ClientSize. Значением этого свойства является ссылка на объект класса Size из пространства имен System.Drawing (стр.15). 5. Первая кнопка создается в стр.17. Ее положение и размер задаются свойствами Left, Top, Width и Heigh (стр.18-21). 6. Вторая кнопка создается в стр.23. Ее положение и размер задаются другим способом – с помощью свойства Bounds (границы), значением которого является объект Rectangle (прямоугольник) (стр.24). В дальнейшем выбирайте тот способ управления, который Вам больше подходит. 7. Следующий момент очень важен и часто вызывает на практике ошибки. Объекты кнопки пока никак не связаны с объектом-формой. Поэтому программа хотя и создает все объекты, но не показывает кнопки внутри формы. Для показа кнопок на форме их необходимо добавить в специальный контейнер формы, который доступен через свойство Controls. Это делается методом Add в стр. 26 и 27. 8. Наконец в стр. 29 форма показывается на экране и начинает взаимодействовать с пользователем. Элемент управления Timer Модель выполнения оконного приложения существенно ориентирована на события. Можно говорить, что оконное приложение функционирует только в ответ на происходящие с ним (его элементами) события. Отсюда можно сделать вывод – если пользователь не дотрагивается до «органов управления» компьютером, программа бездействует в ожидании новых событий. Это означало бы, что мы не можем реализовать большое количество задач, которые демонстрируют автономную, независимую от пользователя динамику.
В качестве простого примера рассмотрим решение следующей задачи. В окне приложения находится небольшая квадратная кнопка, которая каждую секунду перемещается в случайное место, оставаясь целиком в пределах окна. Пользователь пытается успеть щелкнуть по поверхности кнопки. Если ему это удается сделать 3 раза, кнопка перестает двигаться. Для решения этой задачи нужно обеспечить перемещение кнопки независимо от каких-либо действий пользователя. Тем не менее, это перемещение может быть только результатом реакции на некоторое событие. Для разрешения сложившегося противоречия нам нужно событие, которое будет происходить без участия пользователя, и связано с течением времени. Специально для таких задач предусмотрен элемент управления Timer, очень напоминающий обычный будильник. Таймер умеет порождать через указанный интервал времени сигнал – событие Tick. Интервал времени определяется свойством Interval, измеряемым в миллисекундах (1 сек = 1000 миллисекунд). Элемент Timer имеет логическое свойство Enabled: true означает, что Timer включен и генерирует событие Tick, false – Timer выключен. И последнее замечание – Timer не является визуальным элементом. Как следствие, его не нужно помещать в коллекцию Controls объекта-формы. Далее приведем код класса формы, решающий нашу задачу: class MyForm:Form { private Button target; //кнопка-цель private Timer timer; private const int TSize = 50; //размер кнопки private int lifes; //количество "жизней" кнопки public MyForm() { lifes = 3; target = new Button(); Jump(); target.Click += TargetClick; this.Controls.Add(target);
timer = new Timer(); timer.Interval = 1000; timer.Tick += TimerTick; timer.Enabled = true; } private void TimerTick(object sender, EventArgs ea) { Jump(); } private void TargetClick(object sender, EventArgs ea) { lifes--; if (lifes <=0) timer.Tick -= TimerTick; // или timer.Enabled = false; } private void Jump() { Random r = new Random(); int Left=r.Next(0,this.ClientSize.Width-TSize); int Top=r.Next(0,this.ClientSize.Height-TSize); target.Bounds = new Rectangle(Left, Top, TSize, TSize); } } Комментарии Элемент управления ListBox Часто возникает необходимость отображать в окне большое множество информационных элементов на сравнительно небольшом пространстве. Для этого хорошо подходят списки с вертикальными линейками прокрутки. Такие элементы создаются как объекты класса ListBox. Класс ListBox сочетает в себе свойства визуального элемента и знакомого Вам контейнерного класса ArrayList. Для демонстрации возможностей этого элемента создайте оконное приложение, в окне которого располагаются кнопка button1 и список listBox1. Для управления обычными визуальными свойствами у класса ListBox имеются уже знакомые свойства – Height, Width, Top, Left и т.д. Для доступа к «контейнерным» функциям следует использовать свойство Items. Items представляет все множество элементов, находящихся в списке. Возможности этой коллекции сходны с возможностями ArrayList. В первую очередь это означает, что в список с помощью метода Add можно добавлять элементы любых типов. Например, для добавления в список целого числа 1 можно выполнить оператор listBox1.Items.Add(1). Следующий обработчик щелчка по кнопке добавляет в список разные объекты: private void button1_Click(object sender, EventArgs e) { Random r=new Random(); switch (r.Next(1, 5)) { case 1: listBox1.Items.Add(1); break; case 2: listBox1.Items.Add('a'); break; case 3: listBox1.Items.Add("Hi"); break; case 4: listBox1.Items.Add(new Random()); break; } } Все элементы успешно отображаются в списке. Даже объект-генератор случайных чисел:
Объекты любых типов (классов) отображаются в списке с помощью метода ToString своего класса. Если в классе нет собственного метода ToString, действует унаследованный метод – обычно это метод ToString из класса Object, который возвращает строку с полным именем класса. В списке объекты хранятся в первоначальном виде: значимые типы непосредственно копируются в список, а для ссылочных в список помещается только ссылка на объект. Метод Add добавляет элементы в конец списка. Для программного доступа к выбранному в списке элементу используются свойства SelectedIndex (номер выбранного элемента) и SelectedItem(сам выбранный элемент, это свойство имеет тип Object). Добавьте на форму еще одну кнопку (button2). Сделаем так, чтобы в результате щелчка по кнопке, в заголовке формы отображался выбранный элемент. Для этого напишем следующий обработчик: private void button2_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex!= -1) Text = Convert.ToString(listBox1.SelectedItem); else Text = "Элемент не выбран"; } Здесь учтена ситуация, когда в списке ничего не выбрано. В этом случае свойство SelectedIndex равно -1. Наконец, для взаимодействия с пользователем элемент ListBox обычно использует событие SelectedIndexChanged. Это событие происходит в любом случае изменения номера выбранного элемента: - в случае выбора пользователем элемента списка мышью; - в случае выбора пользователем элемента списка клавиатурой; - изменение значения свойства SelectedIndex программным путем. Рассмотрим следующий пример обработчика этого события: private void listBox1_SelectedIndexChanged(object sender, EventArgs e) { if ((listBox1.SelectedIndex < 5) && (listBox1.SelectedIndex < listBox1.Items.Count-1)) listBox1.SelectedIndex++; } Если пользователь выбирает мышью некоторый элемент в списке, возникает первое событие SelectedIndexChanged. Далее при выполнении условия оператора if осуществляется программное увеличение свойства SelectedIndex. Это в свою очередь приводит к возникновению второго события SelectedIndexChanged, его обработке и т.д. Этот процесс останавливается благодаря условию if либо на пятом элементе списка, либо в конце списка. Далее приводятся другие популярные средства управления коллекцией Items: public int Count Свойство, позволяющее узнать количество элементов в коллекции public void AddRange (Object[] items) Добавление в коллекцию массива объектов public void AddRange (ObjectCollection value) Добавление в коллекцию содержимого другого списка public virtual void Clear () Очистка содержимого коллекции public bool Contains (Object value) Определяет, найден ли данный объект в коллекции public int IndexOf (Object value)
Определяет позицию данного элемента в коллекции (-1, если не найден) public void Insert (int index,Object item) Добавляет данный объект в коллекцию в указанную позицию public void Remove (Object value) Удаляет данный элемент из коллекции public void RemoveAt (int index) Удаляет из коллекции объект в указанной позиции Этот перечень еще раз подтверждает сходство коллекции Items с объектами ArrayList. Естественно, коллекцию Items можно индексировать. Файл Program.cs class Program {... static void Main() {... Application.Run(new Form1()); } } Файл Form1.cs public partial class Form1: Form { public Form1() { InitializeComponent(); } // обработчики событий private void button1_Click(object sender, EventArgs e) {...} ... } Файл Form1.Designer.cs partial class Form1 {... #region Windows Form Designer generated code private void InitializeComponent() { //создание объектов-элементов управления this.button1 = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); // button1 this.button1.Location = new System.Drawing.Point(192, 23); ... this.button1.Click += new System.EventHandler(this.button1_Click); // label1 ... // textBox1 ... // Form1 ... this.Controls.Add(this.textBox1); this.Controls.Add(this.label1); this.Controls.Add(this.button1); } #endregion //описание переменных для элементов управления private System.Windows.Forms.Button button1; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox textBox1; } Далее можно рассмотреть несколько других примеров: - крестики-нолики. Дальнейшая логика курса – рассмотрим способы постоянного хранения. Тогда можно будет рассмотреть архитектурные принципы, основанные на разделении на бизнес-логику, визуальный интерфейс и источник данных. Сохранение результатов Возможность хранить информацию в постоянной памяти является необходимым свойством большинства программных приложений. Для этого используются несколько различных подходов: 1. Файловый ввод-вывод. 2. Механизм сериализации. 3. Базы данных. Далее рассмотрим, как практически организовать использование постоянной памяти с помощью файлов и сериализации. Работа с базами данных в этом пособии не рассматривается. Работа с файлами – наиболее традиционный способ использования постоянной памяти. Для этого в С# имеется множество классов, содержащихся в пространстве имен System.IO. Классы этого пространства имен можно разбить на 2 категории: 1. Классы, управляющие объектами файловой системы. 2. Классы, использующие потоки. Создание каталога. di1.Create(); Удаление каталога di1.Delete(); Если удаляемый каталог не пуст, возникает исключение. Работа с файлами Для выполнения задач, связанных с файлами, можно использовать класс FileInfo. Для получения списка файлов в папке используется статический метод GetFiles класса DirectoryInfo. У методов GetDirectories и GetFiles имеется перегруженный вариант со вторым параметром, в котором можно задать шаблон (маску) интересующих папок или файлов. Например, Directory.GetFiles(@"d:\MyWork", "*.doc") вернет массив с именами Word-файлов в папке d:\MyWork.
Стандартные диалоговые окна
Создадим оконное приложение, позволяющее объединять содержимое двух выбранных пользователем файлов и сохранять их в третьем. Интерфейс программы очень прост: всего три кнопки в окне. Чтобы обеспечить правильную последовательность действий пользователя, будем управлять доступностью кнопок. public partial class Form1: Form { public Form1() { InitializeComponent(); ofdSourceFile.InitialDirectory = "c:\\"; ofdSourceFile.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"; } private void Form1_Load(object sender, EventArgs e) { btnSrcFile1.Enabled = true; btnSrcFile2.Enabled = false; btnSaveFile.Enabled = false; } private void btnSrcFile1_Click(object sender, EventArgs e) { btnSrcFile1.Enabled = false; OpenAndReadFile(); btnSrcFile2.Enabled = true; } private void btnSrcFile2_Click(object sender, EventArgs e) { btnSrcFile2.Enabled = false; OpenAndReadFile(); btnSaveFile.Enabled = true; } private void OpenAndReadFile() { StreamReader sr; if (ofdSourceFile.ShowDialog() == DialogResult.OK) { if (ofdSourceFile.ShowDialog() == DialogResult.OK) { sr = new StreamReader(ofdSourceFile.FileName); // сюда можно вставить код для чтения из файла sr.Close(); } } } private void btnSaveFile_Click(object sender, EventArgs e) { btnSaveFile.Enabled = false; StreamWriter sw; if (sfdSaveFile.ShowDialog() == DialogResult.OK) { sw = new StreamWriter(sfdSaveFile.FileName); // сюда можно вставить код для записи в файл sw.Close(); } } } Здесь используется переменная ofdSourceFile, которая описана как OpenFileDialog. Это описание генерируется дизайнером в ответ на перетаскивание на форму соответствующего элемента управления. Часто целесообразнее описать такую переменную как локальную в рамках метода-обработчика. Обратите внимание на то, что текст приложения еще не завершен – необходимо реализовать чтение из двух файлов и запись их содержимого в третий файл. Сериализация Использование ранее рассмотренных простых средств файлового ввода-вывода оказывается совершенно неудобным для постоянного хранения сложных объектов с разнообразной и даже динамически меняющейся структурой. Для подобных случаев предлагается использовать поддерживаемый в.NET механизм сериализации. Буквальный перевод этого термина означает преобразование информационных объектов в линейную хранимую форму и обратную реконструкцию линейного представления в объектную структуру. Пространства имен System.Runtime.Serialization.Formatters.Binary; Синтаксическая форма сериализации выглядит довольно просто: [Serializable] public class Radio { public bool Autosearch; public double[] stations; [NonSerialized] public string radioed = “XF-552RR6”; } Остальные классы нашего примера: [Serializable] public class Car { public Radio theRadio=new Radio(); public bool Is4Wheel; } [Serializable] public class JamesBondCar: Car { public bool canFly; public bool canShoot; } public class Program { static void Main() { JamesBondCar jbc = new JamesBondCar(); jbc.canFly = false; jbc.canShoot = true; jbc.theRadio.stations = new double[]{88.8, 99.9, 103.7}; jbc.Is4Wheel=true; // Теперь сохраним объект в файле user. dat. BinaryFormatter binFormat = new BinaryFormatter(); Stream fStream = new FileStream(“user.dat", FileMode.Create, FileAccess.Write, FileShare.None); binFormat. Serialize (fStream, jbc); fStream.Close(); } } В приведенном примере сериализация осуществлялась в компактном бинарном формате с помощью класса BinaryFormatter. Часто практичнее сохранят в формате XML с помощью другого класса-«форматизатора» SoapFormatter. Такая простота использования сериализации может вызвать недооценку сложности того, что происходит за кулисами. Ведь сериализуемый объект может быть производным классом и содержать внутренние достаточно сложные переменные-объекты и, даже, коллекции объектов. В этом случае процесс сериализации должен быть выполнен на всех уровнях, либо, если этого не требуется, быть настолько управляемым, чтобы регулировать глубину сериализации. Объектные графы Для лучшего представления о том, как выполняется процесс сериализации, удобно использовать так называемые объектные графы. Представим, что имеются следующие классы. «Автомобиль», «Радио» (класс «Автомобиль» содержит переменную этого типа) и «Автомобиль Джеймса Бонда» (производный от «Автомобиль»). Текстовое представление этого графа (которое строит CLR) выглядит так: [Computer 3, ref 2], [CPU 2], [Notebook 1, ref 3, ref 2] Таким образом, на графе присутствуют отношения двух типов – наследование и композиция. При сериализации объекта класса Notebook объектный граф поможет учесть все его связи, в том числе завуалированную связь с объектом CPU. Если Вам не нужно осуществлять сериализацию всех переменных объекта (выборочная сериализация), пометьте несериализуемые переменные атрибутом [NonSerialized]. Замечания. 1. Атрибут [Serializable] не наследуется. (в Справке сказано, что класс с этим атрибутом cannot be inherited!) 2. Сериализация с помощью BinaryFormatter сохраняет все переменные объекта. Сериализация с помощью SoapFormatter или XmlSerializer сохраняет только открытые переменные и закрытые переменные, доступные через открытые свойства (а как это?). Десериализация vs Singleton Формат сериализации - BinaryFormatter – компактный двоичный формат. Требует подключения System.Runtime.Serialization.Formatters.Binary. - SoapFormatter – в виде сообщения SOAP. Требует подключения System.Runtime.Serialization.Formatters.Soap. В проект нужно добавить ссылку на System.Runtime.Serialization.Formatters.Soap.dll. Этот вариант удобен при передаче данных по протоколу HTTP. - XmlSerializer – в виде «чистого» XML. Требует подключения System.Xml.Serialization. Объекты всех этих типов для осуществления сериализации реализуют методы Serialize и Deserialize. Реконструкция объектов // Чтение JamesBondCar из двоичного файла. fStream = File.OpenRead("CarData"); JamesBondCar carFromDisk = (JamesBondCar)binFormat. Deserialize (fStream); Console.WriteLine("Может ли машина летать? {0}", carFromDisk.canFly); fStream.Close();
Другие элементы управления Label – поле вывода текста (метка) TextBox – поле ввода и редактирования текста Button – командная кнопка CheckBox – переключатель не исключающего выбора RadioButton – переключатель исключающего выбора ListBox – список выбора ComboBox – комбинированный список выбора MainMenu – главное меню окна ContextMenu – контекстное меню
MessageBox Show Label Refresh Paint PaintEventArgs Button xEnabled SetBounds TextBox Text Handled Focus TextChanged KeyPress KeyPress KeyPressedEventArgs KeyChar ComboBox DropDownStyle SelectedIndex SelectedIndexChanged CheckBox CheckedChanged Checked Form Load Close
FolderBrowserDialog PictureBox DirectoryInfo FileInfo
Timer NumericUpDown
Класс Control Все классы элементов управления и класс Form являются производными от класса Control. Поэтому они имеют доступ к обширной унаследованной функциональности этого класса. Класс System.Windows.Forms.Control задает общее поведение, ожидаемое от любого GUI-типа. Базовые члены Control позволяют указать размер и позицию элемента управления, выполнить захват событий клавиатуры и мыши, получить и установить фокус ввода, задать и изменить видимость членов и т.д. В табл. 19.4 определяются некоторые (но, конечно же, не все) свойства, сгруппированные по функциональности. Таблица 19.4. Базовые свойства типа Control (большинство свойств обеспечивают доступ как по чтению, так и по записи)
Кроме того, класс Control определяет ряд событий, позволяющих реагировать на изменение состояния мыши, клавиатуры, действия выделения и перетаскивания объектов (а также на многие другие действия). В табл. 19.5 предлагается список некоторых (но далеко не всех) событий, сгруппированных по функциональности. Таблица 19.5. События типа Control
Наконец, базовый класс Control определяет целый ряд методов, позволяющих взаимодействовать с любым типом, производным от Control. При ближайшем рассмотрении методов Control вы обнаружите, что многие из них имеют префикс On, за которым следует имя соответствующего события (OnMouseMove, OnKeyUp, OnPaint и т.д.). Каждый из этих снабженных префиксом виртуальных методов представляет собой обработчик соответствующего события, заданный по умолчанию. Переопределив такой виртуальный член, вы получаете возможность выполнить необходимую предварительную (или заключительную) обработку данных, перед вызовом (или после вызова) родительской реализации обработчика события. public class MainWindow: Form { protected override void OnMouseDown(MouseEventArgs e) { // Добавленный программный код для события MouseDown. // Вызов родительской реализации. base.OnMouseDown(e); } } Это может оказаться полезным, например, при создании пользовательских элементов управления, которые получаются из стандартных (см. главу 21), но чаще всего вы будете использовать обработку событий в рамках стандартного синтаксиса событий С# (именно это предлагается средствами проектирования Visual Studio 2005 по умолчанию). В этом случае среда разработки вызовет пользовательский обработчик события после завершения работы родительской реализации. public class MainWindow: Form { public MainWindow () { MouseDown+=new MouseEventHandler(MainWindow_MouseDown); } void MainWindow_MouseDown(object sender, MouseEventArgs e) { // Добавленный программный код для события MouseDown. } } Кроме методов вида OnХХХ(), есть несколько других методов, о которые вам следует знать.
Несомненно, класс Control определяет и другие свойства, методы и события в дополнение к тем, которые вы только что рассмотрели. Но и сейчас вы должны иметь достаточно хорошее представление об общих функциональных возможностях этого базового класса. Давайте рассмотрим примеры, позволяющие увидеть указанный класс в действии. Ответ на события MouseMove Далее, мы должны обработать событие MouseMove. Целью является отображение текущих координат (х, у) указателя в области заголовка формы. Все связанные с состоянием мыши события (MouseMove, MouseUp и т.д.) работают в паре с делегатом MouseEventHandler, способным вызвать любой метод, соответствующий следующей сигнатуре. void MyMouseHandler(object sender, MouseEventArgs e); Поступающая на вход структура MouseEventArgs расширяет общий базовый класс EventArgs путем добавления целого ряда членов, специально предназначенных для обработки действий мыши (табл. 19.6). Таблица 19.6. Свойства типа MouseEventArgs
Вот обновленный класс MainForm, в котором обработка события MouseMove происходит так, как предполагается выше. public class MainForm: Form { public MainForm () {... // Для обработки события MouseMove. MouseMove += new MouseEventHandler(MainForm_MouseMove); } // Обработчик события MouseMove. public void MainForm_MouseMove (object sender,MouseEventArgs e) { Text = string.Format("Текущая позиция указателя: ({0}, {1})", e.X, e.Y); } } Если теперь запустить программу и поместить указатель мыши на форму, вы увидите текущие значения координат (х, у) указателя, отображенные в области заголовка соответствующего окна (рис. 19.4). Рис. 19.4. Мониторинг движения мыши Ответ на события клавиатуры Обработка ввода с клавиатуры почти идентична обработке событий мыши. События KeyUp и KeyDown работают в паре с делегатом KeyEventHandler, который может указывать на любой метод, получающий объект общего вида в качестве первого параметра, и KeyEventArgs — в качестве второго. void MyKeyboardHandler(object sender, KeyEventArgs e); Описания членов KeyEventArgs предлагаются в табл. 19.7. Таблица 19.7. Свойства типа KeyEventArgs
Измените объект MainForm, чтобы реализовать обработку события KeyUp. В окне сообщения отобразите название нажатой клавиши, используя свойство KeyCode. public class MainForm: Form { public MainForm () { // Для отслеживания событий KeyUp. KeyUp += new KeyEventHandler(MainForm_KeyUp); } private void MainForm_KeyUp(object sender, KeyEventArgs e) { MessageBox.Show(e.KeyCode.ToString(),"Нажата клавиша!"); } } Скомпилируйте и запустите программу. Теперь вы должны иметь возможность не только определить, какой кнопкой мыши был выполнен щелчок, но и то, какая была нажата клавиша на клавиатуре. На этом мы завершим обсуждение функциональных возможностей базового класса Control и перейдем к обсуждению роли Form. Button Компонент Button представляет собой командную кнопку. Свойства компонента приведены в табл. 2.2. Таблица. 2.2. Свойства компонента Button
ComboBox Компонент ComboBox представляет собой комбинацию поля редактирования и списка, что дает возможность ввести данные путем набора на клавиатуре или выбором из списка. Свойства компонента приведены в табл. 2.3. Таблица 2.3. Свойства компонента CamboBox
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2021-12-15; просмотров: 45; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.129.23.214 (0.299 с.) |