Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Классы Application и Form
Наследование форм
До сих пор мы делали все неправильно, потому, что создавали в своем классе композицию объектов Form. Поэтому мы имели возможность использовать только общедоступные ( public ) методы и свойства этого класса. Но класс Form имеет подавляющее большинство свойств и методов, доступных для наследников ( protected ). Поэтому более правильным будет подход создания нашего класса как наследника класса Form с последующим расширением его функциональности. Следует помнить, что C# поддерживает только одиночное наследование.
-
Переименуйте в панели Solution Explorer файл FirstClass в DerivedClass
-
То же самое сделайте в коде этого файла ( либо через панель Properties, предварительно выделив через Object Browser или через Class View ), переименовав имя класса в DerivedClass
-
Объявите класс DerivedClass наследующим базовому классу Form
public class DerivedClass : Form
-
Внесите изменения, чтобы класс выглядел так
using System; using System.Windows.Forms; using System.Drawing; namespace FirstProject { public class DerivedClass : Form { static void Main() { DerivedClass frm = new DerivedClass(); frm.Text = "Наш класс - наследник от Form"; frm.BackColor = Color.Red; Application.Run(frm); } } }Листинг 12.22 . Наш класс наследует от класса Form
При создании экземпляра нашего класса в функции Main() мы использовали синтаксис вызова конструктора по умолчанию. Круглые скобки в этом случае всегда обязательны при создании экземпляра класса. Но если бы мы определили в своем классе хотя бы один конструктор, то система по умолчанию нам его уже не предоставит и нужно объявлять свой конструктор по умолчанию, пусть даже с пустым телом.
using System; using System.Windows.Forms; using System.Drawing; namespace FirstProject { public class DerivedClass : Form { int width = 600, height = 300; // Общий конструктор public DerivedClass(int width, int height) { Width = width; Height = height; Text = "Общий конструктор"; BackColor = Color.Red; } // Конструктор по умолчанию public DerivedClass() { Width = width; Height = height; Text = "Конструктор по умолчанию"; BackColor = Color.Blue; } static void Main() { DerivedClass frm = new DerivedClass(300, 600); Application.Run(frm); } } }Листинг 12.23 . Несколько перегружаемых конструкторов
Вынесение точки входа в отдельный класс
Разгрузим функцию Main от лишнего кода, да и вынесем ее в другой класс (свой единоличный), чтобы не засорять пользовательский класс несвойственным ему кодом. Функция Main должна обязательно принадлежать какому-нибудь классу, поскольку глобальные функции в C# запрещены.
using System; using System.Windows.Forms; using System.Drawing; namespace FirstProject { public class DerivedClass : Form { public DerivedClass()// Конструктор { // Прямое обращение к свойствам класса Form Text = "Наследник от Form"; BackColor = Color.Red; StartPosition = FormStartPosition.CenterScreen; this.Height /= 2; // this - удобно для IntelliSense } } class EntryPoint { static void Main() { // Создание экземпляра и передача // его в главный цикл сообщений // Так все и делают !!! Application.Run(new DerivedClass()); } } }Листинг 12.24 . Вынесение точки входа в отдельный класс
Устранение неопределенности при нескольких точках входа
В программе функция Main может размещаться в нескольких класса. В этом случае разработчик должен определить стартовый класс.
using System; using System.Windows.Forms; using System.Drawing; namespace FirstProject { public class DerivedClass : Form { int width = 600, height = 300; // Общий конструктор public DerivedClass(int width, int height) { Width = width; Height = height; Text = "Общий конструктор"; BackColor = Color.Red; } // Конструктор по умолчанию public DerivedClass() { Width = width; Height = height; Text = "Конструктор по умолчанию"; BackColor = Color.Blue; } static void Main() { // Создание экземпляра и передача // его в главный цикл сообщений // Так все и делают !!! Application.Run(new DerivedClass(300, 600)); } } class EntryPoint { static void Main() { // Создание экземпляра и передача // его в главный цикл сообщений // Так все и делают !!! Application.Run(new DerivedClass()); } } }Листинг 12.25 . Две точки входа в одном приложении
При запуске приложения будет ошибка о неопределенной точке входа. Теперь нужно определить, какой из классов, содержащих точки входа, будет стартовым в приложении.
-
Выполните команду главного меню оболочки Project/Properties и установите в открывшемся окне вкладки Common Properties/General параметр Startup Object в значение класса с нужной точкой входа.
Отключение консольного окна
Операционная система при запуске нашего приложения параллельно создает и консольное окно, поскольку имеет установку на то, что тип приложения является консольным. Отменим эту установку для компилятора.
-
Выполните команду главного меню оболочки Project/Properties
-
Установите параметр Output Type компилятора в значение Windows Application. Примените установку и закройте окно.
-
Запустите приложение и убедитесь, что консольное окно больше не появляется.
-
Верните таким же способом режим компилятора в значение Console Application, поскольку для испытаний средств языка C# такой режим нам еще нужен.
Переопределение стандартного обработчика, наследуемого из базового класса формы
Теперь, вместо того, чтобы самому регистрировать событие Paint и конструировать его обработчик, мы воспользуемся унаследованным от класса System.Windows.Forms.Control обработчиком OnPaint(),который вызывается формой автоматически при разрушении ее вида. Мы хотим контролировать этот обработчик своим кодом. В базовом классе этот обработчик объявлен виртуальным ( virtual ), поэтому его нужно переопределить в наследнике с ключевым словом override.
using System; using System.Windows.Forms; using System.Drawing; namespace FirstProject { public class DerivedClass : Form { public DerivedClass()// Конструктор { // Прямое обращение к свойствам класса Form Text = "Переопределение наследуемого " + "обработчика OnPaint"; BackColor = Color.Blue;// Синий фон StartPosition = FormStartPosition.CenterScreen; // this - удобнее для вызова IntelliSense this.Height /= 2; this.Width *= 2; } // Замещающий метод обработки события Paint // Переопределение наследуемого обработчика OnPaint() protected override void OnPaint(PaintEventArgs e) // Набрать вручную !!! { System.Drawing.Graphics gr = e.Graphics; System.String str = "Привет из замещенного " + "обработчика OnPaint"; System.Int32 x = 0, y = 0; // то же, что int - псевдоним gr.DrawString(str, Font, // Применить как у владельца (формы) Brushes.White, // Белый текст x, y); // Привязка текста к клиентской области Console.WriteLine("Сработал замещенный " + "обработчик OnPaint"); // Обработчик базового класса base.OnPaint (e); } } class EntryPoint { static void Main() { // Создание экземпляра и передача // его в главный цикл сообщений // Так все и делают !!! Application.Run(new DerivedClass()); } } }Листинг 12.26 . Переопределение наследуемого обработчика OnPaint()