}
Добавляем обработчик пункта меню Save формы frmmain:
private void mnuSave_Click(object sender, EventArgs e) {
saveFileDialog1.Filter = "Text Files (*.txt)|*.txt|All Files(*.*)|*.*";
if (saveFileDialog1.ShowDialog() == .DialogResult. OK) {
//Переключаем фокус на данную форму.
blank frm = (blank)(this. ActiveMdiChild);
//Вызываем метод Save формы blank
frm. Save(saveFileDialog1.FileName);
frm. MdiParent = this;
frm. DocName = saveFileDialog1.FileName;
frm. Text = frm. DocName;
}
}
Теперь файлы можно открывать, редактировать и сохранять. Однако, при сохранении внесенных изменений в уже сохраненном файле вместо его перезаписи вновь появляется окно SaveFileDialog. Изменим нашу программу так, чтобы можно было сохранять и перезаписывать файл. В конструкторе формы frmmain после InitializeComponent отключим доступность пункта меню Save: mnuSave. Enabled = false;
Переключаемся в режим дизайна формы frmmain и добавляем пункт меню Save As после пункта Save. Устанавливаем следующие свойства этого пункта: Name — mnuSaveAs, Shortcut — Ctrl+Shift+S, Text Save &As. В обработчике Save As вставляем вырезанный обработчик пункта Save и добавляем включение доступности Save: mnuSave. Enabled = true;
Сохранять изменения требуется как в только что сохраненных документах, так и в документах, созданных ранее и открытых для редактирования. Поэтому добавим в метод Open включение доступности пункта меню Save:
private void mnuOpen_Click(object sender, EventArgs e) {
mnuSave. Enabled = true;
}
В обработчике пункта Save добавим простую перезапись файла — вызов метода Save формы blank:
private void mnuSave_Click(object sender, EventArgs e) {
//Переключаем фокус на данную форму.
blank frm = (blank) (this. ActiveMdiChild);
//Вызываем метод Save формы blank
frm. Save(frm. DocName);
}
Теперь, если мы работаем с несохраненным документом, пункт Save неактивен, после сохранения он становится активным и, кроме того, работает сочетание клавиш Ctrl+S. Можно сохранить копию текущего документа, вновь воспользовавшись пунктом меню Save As.
Сохранение файла при закрытии формы
Всякий раз, когда мы закрываем документ Microsoft Word, в который внесли изменения, появляется окно предупреждения, предлагающее сохранить документ. Добавим аналогичную функцию в наше приложение. В классе blank создаем переменную, которая будет фиксировать сохранение документа:
public bool IsSaved = false;
В обработчик методов Save и Save As формы frmmain добавляем изменение значения этой переменной:
private void mnuSave_Click(object sender, EventArgs e) {
…
frm. IsSaved = true;
}
private void mnuSaveAs_Click(object sender, EventArgs e) {
…
frm. IsSaved = true;
}
Переходим в режим дизайна формы blank и в окне свойств переключаемся на события формы, щелкнув на значок с молнией. В поле события FormClosed дважды щелкаем и переходим в код:
private void blank_FormClosed(object sender, FormClosedEventArgs e) {
if(IsSaved ==true)
if(MessageBox. Show("Do you want save changes in " + this. DocName + "?",
"Message", MessageBoxButtons. YesNo,
MessageBoxIcon. Question) == .DialogResult. Yes) //Если было Yes
{
this. Save(this. DocName);
}
}
OpenFileDialog и SaveFileDialog для SDI-приложений
При создании MDI-приложений приходится разделять код для открытия и сохранения файлов, как мы делали для приложения NotepadC#. В случае SDI-приложений весь код будет находиться в одном обработчике. Cоздаем новое приложение, называем его TextEditor. На форме размещаем элемент управления TextBox и устанавливаем следующие свойства:
TextBox, свойство | Значение |
Name | txtBox |
Dock | Fill |
Multiline | true |
Text | Да |
Добавляем на форму элемент menuStrip1, в котором будет всего три пункта — File, Open и Save (свойства этих пунктов см. в таблице 6). Из окна ToolBox перетаскиваем элементы OpenFileDialog и SaveFileDialog — свойства этих элементов в точности такие же, как и у диалогов приложения NotepadC#. Переходим в код формы.
Добавляем обработчик для пункта меню Open:
private void mnuOpen_Click(object sender, EventArgs e){
openFileDialog1.ShowDialog();
String fileName = openFileDialog1.FileName;
FileStream filestream= File. Open(fileName, FileMode. Open, FileAccess. Read);
if(filestream != null) {
StreamReader streamreader = new StreamReader(filestream);
txtBox.Text = streamreader.ReadToEnd();
filestream. Close();
}
}
Добавляем обработчик для пункта меню Save:
private void mnuSave_Click(object sender, EventArgs e) {
saveFileDialog1.ShowDialog();
String^ fileName=saveFileDialog1.FileName;
FileStream filestream = File. Open(fileName, FileMode. Create, FileAccess. Write);
if(filestream != null) {
StreamWriter streamwriter = new StreamWriter(filestream);
streamwriter. Write(txtBox. Text);
streamwriter.Flush();
filestream.Close();
}
}
Задания к лабораторной работе
1. Создать учебные приложения Программа1 – Программа 4 и разобрать принцип их работы. Поместить примеры работы программ и их коды с комментариями в отчет.
2. Создать текстовый редактор NotepadC#. Добавив недостающие пункты меню и функции.
3. На основании лаб. работы 3 создать MDI-приложение. Информация в окне должна отображаться в виде таблицы. Иметь возможность делать выборку данных по различным критериям. Переносить данные из одной формы в другую.
4. Добавить формы для ввода дополнительной информации об объекте и фото объекта.
5. Добавить пункты меню для сохранения объектов в файл и загрузки. При сохранении использовать стандартные диалоговые окна и механизм сериализации. В класс добавить поле дата создания объекта. Это поле не сериализовать, а при десериализации заново устанавливать по системной дате.
Вопросы к защите лабораторной работы.
Что такое поток? Какой класс является родоначальником всех потоков? Какие бывают потоки? В каких форматах можно сохранять файловые потоки? Режимы работы с файлом. Основные методы работы с файлом. Какие возможности имеют классы File, Filelnfo? Что такое сериализация? Для чего она применяется? Что такое десериализация? Для чего она применяется? Как задать сериализацию объектов класса? В каких форматах можно сериализовать данные? Как исключить некоторые свойства объекта при сериализации? Как десериализовать объект? Что такое управляемая сериализация? Как можно задать управляемую сериализацию? Что такое MDI приложение? Как создать такое приложение? Что такое контекстно-зависимое меню? Как создать контекстно-зависимое меню? Какая компонента позволяет отображать на форме рисунок? Какая компонента позволяет сделать табличный вывод данных на форме? Какая компонента служит для ввода текста и многострочного текста на форме? Как создать и вызвать стандартные диалоговые окна: подтверждение действия, сохранение в файл, загрузка из файла?Лабораторная работа 5
Тема: Создание и вывод графический изображений на форму.
Анимация.
Цель работы:
- Изучить приемы рисования, вывода изображений и анимации изображений в Visual .
Теоретические сведения
Система координат, принятая по умолчанию, использует в качестве единицы измерения пиксели, а в качестве исходной точки — верхний левый угол. Координата X определяет смещение вправо, а координата Y — смещение вниз.


Рисунок 5.1 - Система координат, используемая по умолчанию.
Для того чтобы вывести графическое изображение в окне формы необходимо в созданном средствами Visual Studio приложении WindowsApplication вставить в класс формы строку this. Paint += new PaintEventHandler(Form1_Paint); - где Form1 – имя формы, например:
public Form1() {
InitializeComponent();
this. Paint += new PaintEventHandler(Form1_Paint);
}
private void Form1_Paint(Object sender, PaintEventArgs e) {
Graphics g = e.Graphics;
...
}
Методы, определенные в классе Graphic, требуют, указания положения или область для вывода графического объекта. Для передачи методам подобной информации в пространстве имен System. Drawing предусмотрены типы Point, Rectangle, Region и Size.
· Point используется для передачи координат (х, у).
· Rectangle определяет координаты двух точек, которые будут восприняты как верхний левый и нижний правый углы прямоугольника.
· Тип Size определяет размер прямоугольной области в каком-либо измерении (то есть используется для указания высоты или ширины).
· Тип Region необходим для работы с непрямоугольными областями.
Внутренние переменные, используемые для хранения данных в Point, Rectangle и Size, являются целочисленными (то есть относятся к типу int). Если же возникла необходимость указывать координаты или размеры при помощи значений с плавающей запятой (тип float), то можно использовать типы PointF, RectangleF и SizeF.
Таблица 5.1. Члены типа Point (PointF)
Член | Назначение |
X, У | Эти свойства позволяют получать и устанавливать значения координат х и у |
IsEmpty | Это свойство возвращает true, если значения х и у равны нулю |
Offset( ) | Этот метод позволяет произвести смещение точки относительно исходной позиции |
Например, создадим объект типа Point, и координатам X иY присвоим числовые значения.
Point pt = new Point (100, 72);
//Смещаем точку
pt.Offset(20, 20); // в результате координаты точки будут (120, 92)
// Меняем значение координаты X для pt
pt. X = 40; // в результате координаты точки будут (40, 92)
Таблица 5.2. Члены классов Rectangle и RectangleF
Член | Назначение |
!=, = = | Перегруженные операторы, позволяющие сравнивать два прямоугольника |
Inflate( ), Intersect( ), Union( ) | Эти статические методы позволяют увеличивать размеры прямоугольника и создавать новые прямоугольники путем разделения или объединения существующих. |
Тор, Left, Bottom, Right, | Эти свойства устанавливают измерения прямоугольника |
Height, Width | Эти свойства определяют высоту и ширину прямоугольника |
Contains() | Этот метод позволяет определить, попадает ли точка с указанными координатами (или другой прямоугольник) внутрь области, занимаемой прямоугольником |
X, Y | Определяют координаты x и у верхнего левого угла прямоугольника |
Класс Region
Этот класс представляет собой внутреннюю область, занятую геометрической фигурой. Чтобы создать объект этого класса, необходимо передать его конструктору некоторый объект, представляющий собой геометрическую фигуру. Например, есть прямоугольник размером 100 на 100 пикселов. Чтобы получить объект класса Region, соответствующий внутренней области этого прямоугольника, код может быть таким:
// Получаем объект Region для прямоугольника
Rectangle г = new Rectangle(0, 0, 100, 100);
Region rgn = new Region(r);
После того как объект класса Region создан, можно использовать многочисленные члены этого класса. Наиболее важные из них представлены в таблице:
Таблица 5.3. Члены класса Region
Член | Назначение |
Complement() | Дополняет объект Region другими графическими объектами, которые не пересекаются с исходным объектом Region |
Exclude() | Исключает область, занимаемую другим графическим объектом, из области объекта Region |
Intersect() | Перегружен. Уменьшает область, занимаемую исходным объектом Region, до области наложения друг на друга исходного и указанного пользователем объектов Region |
GetBounds() | Возвращает объект класса RectangleF, представляющий прямоугольник, в который точно вписана область, занимаемая объектом Region |
IsEmpty(), MakeEmpty() | Позволяют определить, имеет ли область, занимаемая данным объектом Region, нулевой размер, или установить нулевой размер для области Region |
IsInfinite(), MakeInfinite() | Позволяют определить, является ли область, занимаемая объектом Region, бесконечной, или установить бесконечный размер для данной области |
Translate() | Сдвигает координаты объекта Region на указанную пользователем величину |
Union() | Объединяет указанный объект Region с другим графическим объектом |
Хог() | Объединяет указанный объект Region с другим графическим объектом, исключая при этом область пересечения этих двух объектов |
Вывод графических объектов без события Paint
Бывает так, что вывод графического объекта необходимо произвести не в стандартных ситуациях, то есть не когда возникает событие Paint, а в ответ на другие события. Например, вывести маленький кружок в том месте, где на форме был сделан щелчок мышью. Первое, необходимо получить объект Graphics, а затем выполнить с этим объектом необходимые манипуляции. Объект Graphics можно получить при помощи метода Graphics. FromHwnd(). Обратите внимание, что единственный параметр, передаваемый этому методу, — это значение свойства Handle. Свойство Handle, определено в классе Control и наследуется всеми классами, производными от Control.
private void Form1_MouseDown( Object sender, MouseEventArgs e) {
// Получаем объект Graphics
Graphics g = Graphics. FromHwnd(this. Handle);
// Теперь в месте щелчка мышью рисуем кружок диаметром 10 пикселов
g. DrawEllipse(new Pen(Color. Green), e. X, e. Y, 10, 10);
}
При любой перерисовке формы все кружки, выведенные на форме после щелчков мышью, исчезнут. Чтобы информация о графических объектах сохранялась и использовалась при перерисовке формы самый простой способ — создать внутреннюю коллекцию (например, ArrayList) и помещать туда нужные объекты. Затем к этой коллекции будет обращаться метод OnPaint().
Возможности класса Graphics
Наиболее часто используемые методы этого класса представлены в таблице.
Таблица 5.4. Некоторые методы класса Graphics
Метод | Назначение |
FromHdc(), FromHwnd(), FromImage() | Эти статические методы обеспечивают возможность получения объекта Graphics из элемента управления или изображения |
Clear() | Заполняет объект Graphics выбранным пользователем цветом, удаляя его предыдущее содержимое |
DrawArc() | Этот метод предназначен для вывода дуги. |
DrawEllipse() | Рисует эллипс |
DrawLine() | Рисует линию |
DrawPie() | Рисует сектор |
DrawPolygon( ) | Рисует замкнутую произвольную область |
DrawRectange() | Рисует прямоугольник |
DrawString() | Выводит строку |
FillElllpse() | Рисует закрашенный эллипс |
FillPie() | Рисует закрашенный сектор |
FillPolygon() | Рисует закрашенную криволинейную замкнутую область |
FillRectangle() | Рисует закрашенный прямоугольник |
Класс Pen
Pen - класс пера, имеющий два основных атрибута: цвет и ширину. Пример использования, в проекте типа Windows Application внутри любой функции (например OnPaint или функции – обработчике события нажатия кнопки) введите следующий текст:
System. Drawing. Graphics gr = this. CreateGraphics();
System. Drawing. Pen blue = new Pen(Color. Blue); // синее, ширина: 1
System. Drawing. Pen red = new Pen(Color. Red, 2); // красное, ширина: 2
System. Drawing. Pen green = Pens. Green; // зелёное, ширина: 1
gr. DrawRectangle(blue, 20,20,20,20); // рисуем прямоугольники
gr. DrawRectangle(red, 40,20,20,20);
gr. DrawRectangle(green, 60,20,20,20);
Общий вид функций создания графических примитивов:
DrawRectangle(устройство вывода(класса Pen или Brush), х1,y1, x2, y2);
где х1,y1 – координаты верхнего левого угла, x2, y2 – координаты правого нижнего угла.
DrawLine(устройство вывода(класса Pen или Brush), х1,y1, x2, y2);
где х1,y1 – координаты начала линии, x2, y2 – координаты конца линии
DrawEllipse(устройство вывода(класса Pen или Brush),x , y , высота, ширина);
где х1,y1 – координаты центра.
DrawPie(устройство вывода(класса Pen или Brush),x , y , высота, ширина, начальный угол, насколько градусов повернуть почасовой стрелке);

Чтобы получить сектор изображенный на рисунке необходимо задать значение начального угла 180, значение насколько градусов повернуть – 90
DrawArc(устройство вывода(класса Pen или Brush),x , y , высота, ширина, начальный угол, насколько градусов повернуть почасовой стрелке);
DrawString(строка или строковая переменная, шрифт, кисть, x,y, [формат вывода текста]);
x, y - координаты верхнего левого угла текста
DrawPolygon (устройство вывода (класса Pen или Brush), массив точек типа Point [ ]);
Таблица 5.5. Свойства класса Реn
Свойство | Назначение |
Color | Определяет цвет создаваемых объектом Реn линий |
CustomStartCap, CustomEndCap | Позволяют получить или установить стиль «наконечника» пера, который будет показан в начале линии (StartCap) и в конце линии (EndCap) |
DashCap | Позволяет получить или установить стиль «наконечника» для перьев, рисующих пунктирные линии |
DashOffset | Устанавливает смещение начала пунктира относительно исходной точки пунктирной линии |
DashStyle | Позволяет получить или установить стиль для пунктирных линий, создаваемых при помощи данного объекта Реn |
LineJoin | Позволяет получить или установить стиль объединения при пересечении двух линий, выводимых данным объектом Реn |
Width | Позволяет получить или установить ширину данного пера |
Кроме класса Реn в GDI+ также можно использовать коллекцию заранее определенных перьев (коллекция Pens). При помощи статических свойств коллекции Pens можно мгновенно получить уже готовое перо, без необходимости создавать его вручную. Однако все типы Реn, которые создаются при помощи коллекции Pens, имеют одну и ту же одинаковую ширину, равную 1. Чтобы установить перо для вывода линий определенного стиля необходимо подключить в начале кода using System.Drawing.Drawing2D; затем создавая перо
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 |


