Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 158 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 6:

Создание оконных приложений Windows Forms

Использование наследника класса Form

Правильным подходом является создание пользовательского класса, наследника библиотечного класса Form. В таком классе можно установить все необходимые настройки и обработчики событий, а уж затем в цикл сообщений передавать создаваемый на лету объект этого класса. Настройки можно разместить в конструкторе по умолчанию, который автоматически срабатывает в момент создания объекта. Такой подход избавит функцию Main() от несвойственного ей кода и сделает программу более структурированной (все на своем месте).

После установки отношения наследования между пользовательским классом и библиотечным классом Form наследнику передаются все открытые и защищенные поля, свойства, методы и события. К ним можно обращаться из кода этого класса: настраивать свойства, обрабатывать события. Все действия конечного пользователя над окном будут переданы операционной системой экземпляру класса-наследника как объекту, включенному в цикл сообщений методом Application.Run(), в виде событий, которые мы можем контролировать и генерировать ответы внутри обработчиков.

Любое окно Windows Forms может включать в себя другие элементы управления: кнопки, флажки, радиокнопки, раскрывающиеся и простые списки и т.д. В этом случае элементы управления называются дочерними для графического окна, а само графическое окно будет являться родителем этих элементов.

  • Добавьте к приложению новый класс с именем MyForm, выполнив команду Project/Add Class

Будем использовать пространство имен MyApp проекта, все равно оболочка не отвяжется и при каждом новом создании класса будет генерировать пространство имен. По умолчанию генерируется пространство имен, взятое из имени проекта, если только его не изменить в настройках оболочки


Разделите код из файла Program.cs на два файла так

using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    // Наследует классу графического окна
    class MyForm : Form
    {
        // Конструктор с настройками
        public MyForm()
        {
            this.Text = "Живое окно";
            this.BackColor = Color.AliceBlue;
            // Подписываемся на событие с помощью делегата
            this.Paint += new PaintEventHandler(MyPainter);
            // this.Paint += MyPainter; // Альтернативный синтаксис
                                        // подключения обработчика
            // Шрифт
            this.Font = new Font("Arial", 16, FontStyle.Bold);
            // Ширина окна
            this.Width = this.Height * 2;
            // В центре экрана при запуске
            this.StartPosition = FormStartPosition.CenterScreen;
        }
    
        void MyPainter(object sender, PaintEventArgs e)
        {
            Form frm = (Form)sender;// Привели типы
            // Form frm = sender as Form;   // Альтернативный синтаксис
                                            // приведения типов
            Graphics gr = e.Graphics;// Контекст экрана
            // Создаем и настраиваем точку привязки текстового блока
            StringFormat strfrm = new StringFormat();
            strfrm.Alignment = StringAlignment.Center;// Центр по горизонтали
            strfrm.LineAlignment = StringAlignment.Center;// Центр по вертикали
    
            gr.DrawString("Привет студентам кафедры ПМ и АСУ",
            frm.Font, // Применяется шрифт окна
            new SolidBrush(Color.Red),  // Цвет шрифта
            frm.ClientSize.Width / 2,   // Центр клиентской области по горизонтали
            frm.ClientSize.Height / 2,  // Центр клиентской области по вертикали
            strfrm); // Передаем точку привязки текстового блока
        }
    }
}
Листинг 6.5 . Код файла MyForm.cs
using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    class EntryPoint
    {
        public static void Main()
        {
            Application.Run(new MyForm());// Новое окно
        }
    }
}
Листинг 6.6 . Код файла Program.cs

Результат выполнения будет таким


В конструкторе класса MyForm есть строка подключения обработчика к событию Paint, которое генерируется всякий раз при частичной или полной утрате окна из-за его свертывания, увода за пределы экрана или заслонения другим окном. При возвращении окна на экран автоматически восстанавливается только его заголовок, а о восстановлении клиентской области (содержимого окна) разработчик приложения должен позаботиться сам. Создатели многооконной операционной системы приняли такой порядок специально, чтобы не перегружать ресурсы хранением множества экранов. Они только извещают приложение событием Paint о том, что окно было разрушено и его пора восстановить.

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

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

В качестве примера подпишем наше графическое окно на несколько обработчиков:

  • Paint - окно разрушено и требует перерисовки
  • Click - пользователь щелкнул на клиентской области окна
  • DoubleClick - был двойной щелчок на клиентской области окна
  • Resize - пользователь изменил размер окна
  • Измените код приложения следующим образом
using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    // Наследует классу графического окна
    class MyForm : Form
    {
        // Конструктор с настройками
        public MyForm()
        {
            // Начальная настройка окна
            this.Text = "Подписка событий";
            this.BackColor = SystemColors.Window;
            this.StartPosition = FormStartPosition.CenterScreen;
    
            // Подписка на события окна
            this.Paint += new PaintEventHandler(MyPaint);
            // На событие Click не подписываемся,
            // но обработчик создадим
            // this.Click += new EventHandler(MyClick);
            // Альтернативный синтаксис подписки
            this.DoubleClick += MyDoubleClick;
            this.Resize += MyResize;
        }
    
        // Объявили и инициализировали внутреннее поле
        Random rnd = new Random(); 
    
        void MyPaint(object sender, PaintEventArgs e)
        {
            MessageBox.Show("Окно разрушено!", "Класс MyForm");
            Graphics gr = e.Graphics;// Ссылка на контекст экрана
            // Рисуем разрушенную часть 
            // клиентской области случайным цветом
            gr.Clear(Color.FromArgb(rnd.Next(255),      // Red
                                    rnd.Next(255),      // Green
                                    rnd.Next(255)));    // Blue
        }
    
        // Обработчик события создан,
        // но класс на него не подписался
        void MyClick(object sender, EventArgs e)
        {
            MessageBox.Show("Выполнен одиночный щелчок!", "Класс MyForm");
        }
    
        void MyDoubleClick(object sender, EventArgs e)
        {
            MessageBox.Show("Выполнен двойной щелчок!", "Класс MyForm");
        }
    
        void MyResize(object sender, EventArgs e)
        {
            MessageBox.Show("Размеры окна изменены!", "Класс MyForm");
        }
    }
}
Листинг 6.7 . Код файла MyForm.cs
using System;
using System.Windows.Forms;
using System.Drawing;
    
namespace MyApp
{
    class EntryPoint
    {
        public static void Main()
        {
            Application.Run(new MyForm());// Новое окно
        }
    }
}
Листинг 6.8 . Код файла Program.cs
  • Запустите приложение и получите ошибку компиляции с сообщением, что приложение имеет больше чем одну точку входа: " MyApp.exe' has more than one entry point "
  • В панели Solution Explorer вызовите для узла приложения (корневой узел) контекстное меню и выберите опцию Properties

  • В окне свойств выберите вкладку Application и в поле Startup object установите явно точку входа, находящуюся в классе MyForm

  • Запустите приложение и поманипулируйте с графическим окном как конечный пользователь

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

Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?