Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Другие элементы меню 25 страница




Поэтому в C/C++ применяется схема try/catch блоков, суть которой в следующем. Участок программы, в котором может возникнуть исключительная ситуация оформляется в виде охраняемого try-блока. Если при его выполнении возникает исключительная ситуация, то происходит прерывание выполнения try-блока c классификацией исключения. Это исключение начинает обрабатывать один из catch-блоков, соответствующий типу исключения. В C/C++ применяются две такие схемы. Одна из них – схема с возобновлением – соответствует так называемым структурным или С-исключениям. Вторая схема – без возобновления – соответствует С++ исключениям. В первой схеме обработчик исключения – catch-блок – возвращает управление в некоторую точку try-блока. Во второй схеме управление не возвращается в try-блок.

С некоторыми синтаксическими отличиями схема с возобновлением применяется в языках VB/VBA.

Многообразие подходов к обработке исключений говорит о том, что не найден единый, удовлетворяющий всех подход к обработке исключений. Чуть позже я расскажу о наиболее разумной, с моей точки зрения, схеме. К сожалению, не она применяется в C#.

Схема обработки исключений в C#

Язык C# наследовал схему исключений языка С++, внеся в нее свои коррективы. Рассмотрим схему подробнее и начнем с синтаксиса конструкции try-catch-finally:

try {…}

catch (T1 e1) {…}

catch(Tk ek) {…}

finally {…}

Всюду в тексте модуля, где синтаксически допускается использование блока, этот блок можно сделать охраняемым, добавив ключевое слово try. Вслед за try-блоком могут следовать catch-блоки, называемые блоками-обработчиками исключительных ситуаций, их может быть несколько, они могут и отсутствовать. Завершает эту последовательность finally-блок – блок финализации, который также может отсутствовать. Вся эта конструкция может быть вложенной – в состав try-блока может входить конструкция try-catch-finally.

Выбрасывание исключений. Создание объектов Exception

В теле try-блока может возникнуть исключительная ситуация, приводящая к выбрасыванию исключений. Формально выбрасывание исключения происходит при выполнении оператора throw. Этот оператор, чаще всего, выполняется в недрах операционной системы, когда система команд или функция API не может выполнить свою работу. Но этот оператор может быть частью программного текста try-блока и выполняться, когда в результате проведенного анализа становится понятным, что дальнейшая нормальная работа невозможна.

Синтаксически оператор throw имеет вид:

throw[выражение]

Выражение throw задает объект класса, являющегося наследником класса Exception. Обычно это выражение new, создающее новый объект. Если это выражение отсутствует, то повторно выбрасывается текущее исключение. Если исключение выбрасывается операционной системой, то она сама классифицирует исключение, создает объект соответствующего класса и автоматически заполняет его поля.

В рассматриваемой нами модели исключения являются объектами, класс которых является наследником класса Exception. Этот класс и многочисленные его наследники является частью библиотеки FCL, хотя и разбросаны по разным пространствам имен. Каждый класс задает определенный тип исключения в соответствии с классификацией, принятой в Framework.Net. Вот лишь некоторые классы исключений из пространства имен System: Argument Exception, ArgumentOutOfRangeException, ArithmeticException, BadImageFormatException, DivideByZeroException, OverflowException. В пространстве имен System.IO собраны классы исключений, связанных с проблемами ввода-вывода: DirectoryNotFoundException, FileNotFoundException и многие другие. Имена всех классов исключений заканчиваются словом Exception. Разрешается создавать собственные классы исключений, наследуя их от класса Exception.

При выполнении оператора throw создается объект te, класс TE которого характеризует текущее исключение, а поля содержат информацию о возникшей исключительной ситуации. Выполнение оператора throw приводит к тому, что нормальный процесс вычислений на этом прекращается. Если это происходит в охраняемом try-блоке, то начинается этап «захвата» исключения одним из обработчиков исключений.

Захват исключения

Блок catch – обработчик исключения имеет следующий синтаксис:

catch (T e) {…}

Класс T, указанный в заголовке catch-блока, должен принадлежать классам исключений. Блок catch с формальным аргументом e класса T потенциально способен захватить текущее исключение te класса TE, если и только если объект te совместим по присваиванию c объектом e. Другими словами потенциальная способность захвата означает допустимость присваивания e = te, что возможно, когда класс TE является потомком класса T. Обработчик, класс T которого является классом Exception, является универсальным обработчиком, потенциально он способен захватить любое исключение, поскольку все они являются его потомками.

Потенциальных захватчиков может быть много, исключение захватывает лишь один – тот из них, кто стоит первым в списке проверки. Каков порядок проверки? – довольно естественный. Вначале проверяются обработчики в порядке следования их за try-блоком и первый потенциальный захватчик становится активным, захватывая исключение и выполняя его обработку. Отсюда становится ясно, что порядок следования в списке catch-блоков крайне важен. Первыми идут наиболее специализированные обработчики, далее по мере возрастания универсальности. Так вначале должен идти обработчик исключения DivideByZeroException, а уже за ним –ArithmeticException. Универсальный обработчик, если он есть, должен стоять последним. За этим наблюдает статический контроль типов. Если потенциальных захватчиков в списке catch-блоков нет (сам список может отсутствовать), то происходит переход к списку обработчиков охватывающего блока. Напомню, что try-блок может быть вложен в другой try-блок. Когда же будет исчерпаны списки вложенных блоков, а потенциальный захватчик не будет найден, то произойдет подъем по стеку вызовов. На рис. 23.5 показана цепочка вызовов, начинающаяся с точки «большого взрыва» – процедуры Main.

 

<Рис. 23.5. Цепочка вызовов, хранящаяся в стеке вызовов>

О точке большого взрыва и цепочке вызовов мы говорили еще в лекции 2.

Исключение возникло в последнем вызванном методе этой цепочки – на рисунке это метод r5. Если у этого метода не нашлось обработчиков события, способных обработать исключение, то это пытается сделать метод r4, вызвавший r5. Если вызов r5 находится в охраняемом блоке метода r4, то начнет проверяться список обработчиков в охраняемом блоке метода r4. Этот процесс подъема по списку вызовов будет продолжаться, пока не будет найден обработчик, способный захватить исключение, или не будет достигнута начальная точка – процедура Main. Если и в ней нет потенциального захватчика исключения, то сработает стандартный обработчик исключения, прерывающий выполнение программы с выдачей соответствующего сообщения.

Параллельная работа обработчиков исключений

Обработчику исключения – catch-блоку, захватившему исключение, передается текущее исключение. Анализируя свойства этого объекта, обработчик может понять причину, приведшую к возникновению исключительной ситуации, попытаться ее исправить и в случае успеха продолжить вычисления. Заметьте, в принятой C# схеме без возобновления обработчик исключения не возвращает управление try-блоку, а сам пытается решить проблемы. После завершения catch-блока выполняются операторы текущего метода, следующие за конструкцией try-catch-finally.

Зачастую, обработчик исключения не может исправить ситуацию или может выполнить это лишь частично, предоставив решение оставшейся части проблем вызвавшему методу – предшественнику в цепочке вызовов. Механизм, реализующий такую возможность – это тот же механизм исключений. Как правило, в конце своей работы, обработчик исключения выбрасывает исключение, выполняя оператор throw. При этом у него есть две возможности – повторно выбросить текущее исключение, или выбросить новое исключение, содержащее дополнительную информацию.

Некоторые детали будут пояснены позже при рассмотрении примеров.

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

Блок finally

До сих пор ничего не было сказано о важном участнике схемы обработки исключений – блоке finally. Напомню, рассматриваемая схема является схемой без возобновления. Это означает, что управление вычислением неожиданно покидает try-блок. Просто так этого делать нельзя – нужно выполнить определенную чистку. Прежде всего удаляются все локальные объекты, созданные в процессе работы блока. В языке С++ эта работа требовала вызова деструкторов объектов. В C# благодаря автоматической сборке мусора освобождением памяти можно не заниматься, достаточно освободить стек. Но в блоке try могли быть заняты другие ресурсы – открыты файлы, захвачены некоторые устройства. Освобождение ресурсов, занятых try-блоком, выполняет finally-блок. Если он присутствует, он выполняется всегда, сразу же после завершения работы try-блока, как бы последний не завершался. Блок try может завершиться вполне нормально без всяких происшествий и управление достигнет конца блока, выполнение может прервано оператором throw, управление может передано другому блоку из-за выполнения таких операторов как goto, return – во всех этих случаях прежде чем управление будет передано по предписанному назначению (в том числе прежде чем произойдет захват исключения) предварительно будет выполнен finally-блок, освобождающий ресурсы, занятые try-блоком, параллельно будет происходить освобождение стека от локальных переменных.

Схема Бертрана обработки исключительных ситуаций

Схема обработки исключительных ситуаций, предложенная в языке C# обладает одним существенным изъяном – ее можно применять некорректно. Она позволяет в случае возникновения исключительной ситуации уведомить о ее возникновении и спокойно продолжить работу, что в конечном счете приведет к неверным результатам. Из двух зол – прервать вычисление с уведомлением о невозможности продолжения работы, или закончить вычисления с ошибочным результатом вычисления – следует выбирать первое. Некорректно примененная схема C# приведет к ошибочным результатам. Приведу несколько примеров. Представьте, оформляется заказ на отдых где-нибудь на Канарах. В ходе оформления возникает исключительная ситуация – нет свободных мест в гостинице – обработчик исключения посылает уведомление с принесением извинений, но оформление заказа продолжается. Вероятнее, предпочтительнее отказаться от отдыха на Канарах, и выбрать другое место, чем оказаться без крыши над головой, ночуя на берегу океана. Эта ситуация не является критически важной. А что если в процессе подготовки операции выясняется, что проведение ее в данном случае опасно. Никакие извинения не могут избавить от вреда, нанесенного операцией. Операция должна быть отменена.

Бертран Мейер в книге [1], в которой все механизмы, используемые в объектной технологии, тщательно обосновываются, предложил следующую схему обработки исключительных ситуаций. В основе ее лежит подход к проектированию программной системы на принципах Проектирования по Контракту. Модули программной системы, вызывающие друг друга заключают между собой контракты. Вызывающий модуль обязан обеспечить истинность предусловия, необходимого для корректной работы вызванного модуля. Вызванный модуль обязан гарантировать истинность постусловия по завершению своей работы. Если в вызванном модуле возникает исключительная ситуация, то это означает, что он не может выполнить свою часть контракта. Что должен делать обработчик исключительной ситуации? – у него только две возможности – Retry и Rescue. Первая (Retry)– попытаться внести некоторые коррективы – и вернуть управление охраняемому модулю, который может предпринять очередную попытку выполнить свой контракт. Модуль может, например в следующей попытке запустить другой алгоритм, использовать другой файл, другие данные. Если все закончится успешно, работа модуля соответствует его постусловию, то появление исключительной ситуации можно рассматривать как временные трудности, успешно преодоленные. Если же ситуация возникает вновь и вновь, тогда обработчик события применяет вторую стратегию (Rescue), выбрасывая исключение и передавая управление вызывающему модулю, который и должен теперь попытаться исправить ситуацию. Важная тонкость в схеме, предложенной Бертраном, состоит в том, что исключение, выбрасываемое обработчиком исключения, следует рассматривать не как панику, не как бегство, а как отход на заранее подготовленные позиции. Обработчик исключения должен позаботиться о восстановлении состояния, предшествующего вызову модуля, приведшего к исключительной ситуации, что гарантирует нахождение всей системы в корректном состоянии.

Схема Бертрана является схемой с возобновлением, и она наиболее точно описывает разумную стратегию обработки исключительных ситуаций. Не следует думать, что эта схема не может быть реализована на C#, просто она требует понимания сути и определенной структурной организации модуля. Приведу возможную реализацию такой схемы на C#:

public void Pattern()

{

{

{

bool Danger = false;

Success = true;

MakeJob();

Danger = CheckDanger();

if (Danger)

throw (new MyException());

MakeLastJob();

}

catch (MyException me)

{

if (count > maxcount)

throw (new MyException("Три попытки были безуспешны"));

Success = false; count++;

//корректировка ситуации

Console.WriteLine("Попытка исправить ситуацию!");

level +=1;

}

} while (!Success);

}

Приведу краткие комментарии к этой процедуре, которую можно рассматривать как некоторый образец организации обработки исключительной ситуации:

Конструкция try-catch блоков помещается в цикл do-while(!Success), завершаемый в случае успешной работы охраняемого блока, за чем следит булева переменная Success.

В данном образце предполагается, что в теле охраняемого блока анализируется возможность возникновения исключительной ситуации и в случае обнаружения опасности выбрасывается собственное исключение, класс которого задан программно. В соответствии с этим тело try-блока содержит вызов метода MakeJob, выполняющего некоторую часть работы, после чего вызывается метод CheckDanger, выясняющий, не возникла ли опасность нарушения спецификации и может ли работа быть продолжена. Если все нормально, то выполняется метод MakeLastJob, выполняющий заключительную часть работы. Управление вычислением достигает конца try-блока, он успешно завершается и, поскольку остается истинной переменная Success, значение true которой установлено в начале try-блока, то цикл while, окаймляющий охраняемый блок и его обработчиков исключений, успешно завершается.

Если в методе CheckDanger выясняется, что нормальное продолжение вычислений невозможно, то выбрасывается исключение класса MyException. Это исключение перехватывает обработчик исключения, стоящий за try-блоком, поскольку класс MyException указан, как класс формального аргумента.

Для простоты приведен только один catch-блок. В общем случае их может быть несколько, но все они строятся по единому образцу. Предполагается, что обработчик исключения может сделать несколько попыток исправить ситуацию, после чего повторно выполняется охраняемый блок. Если же число попыток, за которым следит переменная count, превосходит максимально допустимое, то обработчик исключения выбрасывает новое исключение, задавая дополнительную информацию, передавая тем самым обработку ошибки на следующий уровень – вызываемой программе.

Когда число попыток еще не исчерпано, то обработчик исключения переменной Success дает значение false, гарантирующее повтор выполнения try-блока, увеличивает счетчик числа попыток и пытается исправить ситуацию.

Как видите, эта схема реализует два корректных исхода обработки исключительной ситуации – Retry и Rescue – повтору с надеждой выполнить обязательства, и передачи управления вызывающей программе, чтобы она предприняла попытки исправления ситуации, когда вызванная программа не могла с этим справиться.

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

Определим первым делом собственный класс исключений:

public class MyException:Exception

{

public MyException()

{}

public MyException (string message): base (message)

{}

public MyException (string message, Exception e): base (message, e)

{}

}

Минимально, что нужно сделать, определяя свои исключения, – это задать три конструктора класса, вызывающие соответствующие конструкторы базового класса Exception.

В классе Excepts, методом которого является наш образец Pattern, определим следующие поля класса:

Random rnd = new Random();

int level = -10;

bool Success; //true - нормальное завершение

int count =1; // число попыток выполнения

const int maxcount =3;

Определим теперь методы, вызываемые в теле охраняемого блока:

void MakeJob()

{

Console.WriteLine("Подготовительные работы завершены");

}

bool CheckDanger()

{

//проверка качества и возможности продолжения работ

int low = rnd.Next(level,10);

if (low > 6) return (false);

return (true);

}

void MakeLastJob()

{

Console.WriteLine("Все работы завершены успешно");

}

В классе Testing зададим метод, вызывающий метод Pattern:

public void TestPattern()

{

Excepts ex1 = new Excepts();

{

ex1.Pattern();

}

catch (Exception e)

{

Console.WriteLine("исключительная ситуация при вызове Pattern");

Console.WriteLine(e.ToString());

}

}

Обратите внимание, вызов метода Pattern находится внутри охраняемого блока. Поэтому, когда Pattern не справится с обработкой исключительной ситуации, ее обработку возьмет на себя универсальный обработчик, стоящий за try-блоком.

На рис. 23.6 показаны три варианта запуска метода TestPattern. В одном из них исключительной ситуации при вызове метода Pattern вообще не возникало, в другом – ситуация возникала, но коррекция обработчика исключения помогла и при повторе выполнения охраняемого блока в Pattern все прошло нормально. В третьем варианте метод Pattern не смог справиться с исключительной ситуацией, и она обрабатывалась в catch-блоке метода TestPattern.

Класс Exception

Рассмотрим устройство базового класса Exception, что поможет понять, какую информацию может получить обработчик исключения, когда ему передается объект, задающий текущее исключение.

Основными свойствами класса являются:

Message – строка, задающая причину возникновения исключения. Значение этого свойства устанавливается при вызове конструктора класса, когда создается объект, задающий исключение.

HelpLink – ссылка (URL) на файл, содержащий подробную справку о возможной причине возникновения исключительной ситуации и способах ее устранения.

InnerException – ссылка на внутреннее исключение. Когда обработчик исключение выбрасывает новое исключение для передачи обработки на следующий уровень, то текущее исключение становится внутренним для вновь создаваемого исключения.

Source – имя приложения, ставшего причиной исключения.

StackTrace – цепочка вызовов – методы, хранящиеся в стеке вызовов в момент возникновения исключения.

TargetSite – метод, выбросивший исключение.

Из методов класса отметим метод GetBaseException, – при подъеме по цепочке вызовов позволяет получить исходное исключение ­– первопричину возникновения последовательности выбрасываемых исключений.

Класс имеет четыре конструктора, из которых три уже упоминалось. Один из них – конструктор без аргументов, второй – принимает строку, становящуюся свойством Message, третий – имеет еще один аргумент – исключение, передаваемое свойству InnerException.

В предыдущий пример я внес некоторые изменения. В частности, добавил еще один аргумент при вызове конструктора исключения в catch-блоке метода Pattern:

throw (new MyException("Все попытки Pattern безуспешны", me));

В этом случае у создаваемого исключения заполняется свойство InnerExceptions. Для слежения за свойствами исключений добавил метод печати всех свойств, вызываемый во всех обработчиках исключений:

static public void PrintProperties(Exception e)

{

Console.WriteLine("Свойства исключения:");

Console.WriteLine("TargetSite = {0}", e.TargetSite);

Console.WriteLine("Source = {0}", e.Source);

Console.WriteLine("Message = {0}",e.Message);

if (e.InnerException == null)

Console.WriteLine("InnerException = null");

else Console.WriteLine("InnerException = {0}", e.InnerException.Message);

Console.WriteLine("StackTrace = {0}", e.StackTrace);

Console.WriteLine("GetBaseException = {0}", e.GetBaseException());

}

Из-за громоздкости не привожу результаты, но отмечу, что они соответствуют описанию, приведенному в тексте лекции.

В заключение темы исключений хочу еще раз подчеркнуть, что корректное применение механизма исключений должно поддерживаться целенаправленными усилиями программиста. Следует помнить о двух важных правилах:

обработка исключений должна быть направлена не столько на уведомление о возникновении ошибки, сколько на корректировку возникшей ситуации;

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

Вариант 1

64. Классы Debug и Trace:

q имеют разный набор свойств и методов, используемых для класса Debug в интересах отладки, для класса Trace – в интересах трассировки;

q если в конфигурации проекта вызываются методы и свойства класса Debug, то в этой конфигурации не вызываются методы класса Trace и наоборот;

q если в конфигурации вызываются методы и свойства класса Debug, то в этой конфигурации вызываются методы и свойства класса Trace;

q если в конфигурации вызываются методы и свойства класса Trace, то в этой конфигурации вызываются методы и свойства класса Debug;

q классы Trace и Debug имеют одинаковый набор свойств и методов.

65. Отметьте истинные утверждения:

q в тексте охраняемого блока всегда должен присутствовать оператор throw, выбрасывающий исключение;

q никакая программа не может быть корректной по отношению к произвольным спецификациям;

q вывод, поступающий от методов класса Debug, может быть направлен только одному, заранее выбранному слушателю;

q если блок finally сопровождает охраняемый блок, то он всегда будет выполняться;

q правильно организованная отладка позволяет доказать корректность программы.

66. Оператор throw:

q передает управление catch-блоку, следующему за try-блоком;

q может вызываться без аргументов;

q имеет два аргумента;

q вызывает прерывание процесса вычислений охраняемого блока;

q создает исключение – объект класса, производного от Exception.

Вариант 2

68. Блоки catch:

q всегда должны следовать за охраняемым блоком;

q получают управление при возникновении исключительной ситуации и выполняются в порядке их следования;

q только один из блоков, следующих за try-блоков, захватывает управление вычислением;

q выбрасывают исключение для передачи управления вызывающему методу;

q после корректировки причины, вызвавшей исключение, при достижении конца блока возвращают управление в точку возникновения исключения.

69. Отметьте истинные утверждения:

q устойчивость программной системы означает, что малым изменениям спецификации соответствуют малые изменения программного текста;

q невыполнение утверждения Assert приводит к выбрасыванию исключения;

q схема обработки исключений в C# – это схема с возобновлением;

q для каждого проекта по умолчанию создаются две конфигурации;

q блок finally выполняется только, если в охраняемом блоке выброшено исключение.

70. Атрибут условной компиляции Conditional:

q может задаваться для метода и класса;

q может задаваться только для метода;

q может задаваться для метода и отдельного оператора;

q в качестве аргумента принимает только константу условной компиляции;

q в качестве аргумента принимает выражение над константами условной компиляции.

Вариант 3

65. Класс Exception:

q является родительским классом для всех классов, задающих исключение;

q является родительским классом для всех классов библиотеки FCL, задающих исключение, но не классов, определенных пользователем;

q является абстрактным классом;

q имеет метод throw для выбрасывания исключений;

q позволяет задать файл, содержащий подробную справку о причине исключения и способах его устранения.

66. Отметьте истинные высказывания:

q к исключительным относятся только такие ситуации, которые обнаруживаются операционной системой, когда она не может выполнить предписанные программой действия;

q если метод имеет атрибут условной компиляции, то вызов метода может игнорироваться при компиляции программы;

q метод с предусловием False всегда корректен;

q классы Debug и Trace разделяют единую коллекцию слушателей;

q catch-блок не возвращает управление в охраняемый блок.

67. Метод Assert:

q позволяет контролировать корректность выполнения вычислений;

q останавливает вычисления, когда утверждение Assert нарушается;

q является средством периода отладки;

q заменяет механизм исключений;

q при нарушении утверждения открывает специальное диалоговое окно.

 

 

Лекция 24. Организация интерфейса и рисование в формах

Организация интерфейса. Шаблоны форм. Заселение формы элементами управления. Классы элементов управления. Примеры классов. Класс ListBox. Наследование форм. Организация меню, главное меню. Инструментальные панели с кнопками. Рисование в формах. Классы рисования. Кисти и перья.

Ключевые слова: консольные приложения; Windows-приложения; форма; элементы управления; образы клиентских объектов; скрытие и закрытие форм; показа формы; главная форма проекта; модальные и немодальные окна; главная кнопочная форма; элемент управления ListBox; конструкторы; команды; запросы; обработчик события; класс; поля класса; модификаторы доступа; меню; инструментальные панели; кнопки; лементы меню; пункты меню; подменю; главное меню; контекстное меню; абстрактный класс Menu; графика; рисование; рисование в формах; обработчик события Paint; тексты в графическом режиме; геометрические фигуры; нарисовать и закрасить фигуру; класс Pen; класс Brush; класс Graphics; кривые Безье; событие Paint.

Организация интерфейса

Практически все проекты, построенные в наших лекциях, были консольными приложениями. В реальной жизни консольные проекты – это большая редкость. Причина, по которой из 12 возможных типов проектов мы выбирали наименее используемый, понятна. Нашей целью являлось изучение свойств языка, классов библиотеки FCL, для этих целей консольный проект вполне подходит, позволяя избегать введения не относящихся к сути дела деталей. Теперь цель достигнута – основные средства языка C# рассмотрены, учебный курс завершается. Остались важные темы, требующие более подробного рассмотрения, такие, как например работа с атрибутами, создание собственных атрибутов, класс Reflection, работа с файлами и базами данных, но все это предмет будущего курса. Тем не менее, нельзя окончить этот курс, не посвятив две последние лекции Windows-приложениям. Мне бы хотелось, чтобы активные слушатели (читатели) все консольные проекты переделали в Windows-проекты, построив подходящий для них интерфейс.

Первое знакомство с Windows-проектами состоялось в лекции 2, я настоятельно рекомендую перечитать ее, прежде чем продолжить чтение данной лекции. Вкратце напомню, как создается и выполняется Windows-проект, по умолчанию он содержит класс Form1 – наследника класса Form. Этот класс содержит точку входа в проект – процедуру Main, вызывающую статический метод Run класса Application, который создает объект класса Form1 и открывает форму – видимый образ объекта – для интерактивной работы пользователя. Открываемая форма содержит пользовательский интерфейс – окошки, кнопки, списки, другие элементы управления, меню. Все эти элементы способны реагировать на события, возникающие при выполнении пользователем каких-либо действий – нажатии кнопок, ввод текста, выбор пунктов меню.




Поделиться с друзьями:


Дата добавления: 2014-12-25; Просмотров: 520; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.