Файл: Справочник для опытных и как пособие для начинающих программистов. Компактдиск содержит исходные коды примеров из книги.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.01.2024
Просмотров: 942
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
using System.Drawing;
using System.Windows.Forms;
// Другие директивы using удалены, поскольку они не используются в данной программе
namespace ВыборЦвета2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Получаем массив строк имен цветов из перечисления KnownColor.
// Enum.GetNames возвращает массив имен констант в указанном перечислении.
String[] ВсеЦвета = Enum.GetNames(typeof(KnownColor));
listBox1.Items.Clear();
// Добавляем имена всех цветов в список listBoxl:
foreach (string s in ВсеЦвета)
if (s != "Transparent") listBox1.Items.Add(s);
// Цвет Transparent является "прозрачным",
/ / он не поддерживается для формы
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
this.BackColor = Color.FromName(listBoxl .Text);
this.Text = "Цвет: " + listBox1.Text;
}
}
}
Как видно, цикл foreach обеспечивает заполнение списка listBox1 именами цветов в строковом представлении кроме цвета Transparent, поэтому теперь его даже не надо "отсеивать" в процедуре обработки события изменения выбранного индекса.
Мы упомянули 167 констант или 146 цветов из структуры Color. Вообще говоря, в Visual Studio 2010 можно управлять гораздо большим количеством цветов. Система программирования Visual Studio работает с так называемой RGB-моделью управления цветом. Согласно этой модели любой цвет может быть представлен как комбинация красного (Red), зеленого (Green) и синего (Blue) цветов. Долю каждого цвета записывают в один байт: 0 означает отсутствие доли этого цвета, а максимум (255) — максимальное присутствие этого цвета в общей сумме, т. е. в результирующем цвете. Например, функция Color.FromArgb (int red, int green, int blue) возвращает цвет, базируясь на этой модели. Информация о цвете элементарной точки (пиксела) может быть записана в три байта, т. е. 24 бита. При этом говорят, что глубина цвета равна 24 разрядам. Максимальное число, которое можно записать в 24 бита, равно 224 - 1 = 16 777 215 или приблизительно 17 млн. Это означает, что при глубине цвета, равной 24, можно управлять 17 млн цветов (цветовых оттенков).
Предлагаю следующую технологию использования любого цвета при разработке программ. Вначале выбираем цвет, который нам хотелось бы использовать (при разработке каких-либо программ или в Интернете на каком-либо сайте). Существуют программы. сообщающие цвет пиксела, на котором находится курсор мыши, в нескольких принятых кодировках. Одну такую очень маленькую бесплатную программку Pixie вы можете скачать из Интернета по адресу: http://natty.port5.com
илиhttp://www.nattyware.com. Программа сообщает вам цвет пиксела в нескольких форматах, в том числе в формате HTML, например #efebde (этот цвет соответствует цвету Control). ЭТОТ цвет подаете на вход функции ColorTranslator.FromHtml () для
перевода в цвет, понятный той или иной процедуре (методу) С#. Убедиться в работоспособности этих программ можно, открыв соответствующие решения в папках ВыборЦвета1 и ВыборЦвета2.
Пример 35. Печать графических примитивов
В данном разделе приведен пример вывода на печать (на принтер) изображения эллипса. Понятно, что таким же образом можно распечатывать и другие графические примитивы: прямоугольники, отрезки, дуги и т. д. (см. методы объекта Graphics). Для написания данной программы из панели элементов Toolbox в форму перенесем элемент управления PrintDocument. Текст программы приведен в листинге 5.9.
Листинг 5.9. Печать графических примитивов
// Программа выводит на печать (на принтер) изображение эллипса. Понятно, что
// таким же образом можно распечатывать и другие графические примитивы:
// прямоугольники, отрезки, дуги и т. д. (см. методы объекта Graphics)
using System.Drawing;
using System. Windows . Forms ;
// Другие директивы using удалены, поскольку они не используются в данной программе
namespace ПечатьЭллипса
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
printDocumentl.Print();
{
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
// Выводится на печать эллипс красного цвета внутри
// ограничивающего прямоугольника с вершиной в точке (200, 250),
// шириной 300 и высотой 200
Реп Перо = new Pen(Color.Red);
//е.Graphics.DrawEllipse(Перо, new Rectangle(200, 250, 300, 200));
e.Graphics.DrawEllipse(Перо, 50, 50, 150, 150);
}
}
}
Как видно, с целью максимального упрощения программы для генерации события PrintPage Сразу после выполнения Процедуры InitializeComponent вызываем метод PrintDocument1.Print. В обработчике события PrintPage вызываем метод DrawEllipse для построения эллипса без заливки. В комментарии приведен вариант построения эллипса другим способом.
Убедиться в работоспособности программы можно, открыв решение ПечатьЭллипса.sln в папке ПечатьЭллипса.
Пример 36. Печать ВМР-файла
В данном разделе программа выводит на печать графический файл форма BMP. На логическом диске С: заранее подготовим графический файл формата ВMP и назовем его C:\pic.bmp. Этот файл
будет распечатываться на принтере программой, которую мы напишем. Итак, запустим Visual Studio 2010, выберем шаблон Windows Forms Application С#. Затем добавим в форму из панели элемента Toolbox командную кнопку Button и объект PrintDocument. Программный код представлен в листинг 5.10.
Листинг 5.10. Печать ВМР-файла
// Эта программа выводит на печать файл с расширением bmp
using System;
using System.Drawing;
using System.Windows.Forms;
// Другие директивы using удалены, поскольку они не используются в данной программе
namespace ПечатьВМРфайла
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Text = @"Печать файла C:\pic.bmp";
button1.Text = "Печать";
}
private void button1_Click(object sender, EventArgs e)
{ // Пользователь щелкнул на кнопке
try
{
printDocumentl.Print();
}
catch (Exception exc)
{
MessageBox.Show("Ошибка печати на принтере\n", exc.Message);
}
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{ // Это событие возникает, когда вызывают метод Print().
// Рисование содержимого ВМР-файла
е.Graphics.Drawlmage(Image.FromFile(@"C:\pic. bmp"), e.Graphics.VisibleClipBounds);
// Следует ли распечатывать следующую страницу?
е.HasMorePages = false;
}
}
}
Как видно, при нажатии пользователем кнопки вызывается метод printDocument1.print. Этот метод создает событие PrintPage, которое обрабатывался в обработчике printDocument1_PrintPage. Для вывода на принтер вызывается метод Drawlmage рисования содержимого ВМР-файла.
Убедиться в работоспособности программы можно, открыв решение ПечатьВМРфайла.sln в папке ПечатьВМРфайла.
Пример 37. Построение графика
Задача состоит в том, чтобы, используя в качестве исходных данных, например, объемы продаж каких-либо товаров по месяцам, построить график по точкам. Понятно, что таким же образом можно построить любой график для других прикладных целей.
Для решения этой задачи запустим Visual Studio 2010, далее выберем новый проект шаблона Windows Forms Application С#, при этом получим стандартную форму. Перенесем из панели элементов Toolbox в форму элемент управления tureBox и кнопку Button. Далее перейдем на вкладку программного кода и введем текст, представленный в листинге 5.11.
Листинг 5.11. Программа для вывода графика на форму
// Программа рисует график продаж по месяцам. Понятно, что таким же образом
// можно построить любой график по точкам для других прикладных целей
using System;
using System.Drawing;
using System.Windows.Forms;
// Другие директивы using удалены, поскольку они не используются в данной программе
namespace График
{
public partial class Form1: Form
{
// Исходные данные для построения графика (то есть исходные точки):
String[] Months = new string[] {"Янв", "Фев", "Март", "Апр", "Май",
"Июнь", "Июль", "Авг", "Сент", "Окт", "Нояб", "Дек"};
int[] Sales = new int[] {335, 414, 572, 629, 750, 931, 753, 599, 422, 301, 245, 155};
Graphics Графика;
// Далее, создаем объект Bitmap, который имеет
// тот же размер и разрешение, что и PictureBox
Bitmap Растр;
int ОтступСлева = 35; int ОтступСправа = 15;
int ОтступСнизу = 20; int ОтступСверху = 10;
int ДлинаВертОси, ДлинаГоризОси, УГоризОси, Хmax, ХНачЭпюры;
// Шаг градуировки по горизонтальной и вертикальной осям:
double ГоризШаг; int ВертШаг;
//
public Form1()
{
InitializeComponent();
this.Text = " Построение графика ";
button1.Text = "Нарисовать график";
Растр = new Bitmap(pictureBox1.Width, pictureBox1.Height, pictureBox1.CreateGraphics());
// pictureBox1.BorderStyle = BorderStyle.FixedSingle;
УГоризОси = pictureBox1.Height - ОтступСнизу;
Xmax = pictureBox1.Width - ОтступСправа;
ДлинаГоризОси = pictureBox1.Width - (ОтступСлева + ОтступСправа);
ДлинаВертОси = УГоризОси - ОтступСверху;
ГоризШаг = (double)(ДлинаГоризОси / Sales.Length);
ВертШаг = (int)(ДлинаВертОси / 10) ;
ХНачЭпюры = ОтступСлева + 30;
} //
private void button1_Click(object sender, EventArgs e)
{ // Обработка события "щелчок на кнопке":
Графика = Graphics.Fromlmage(Растр);
РисуемОси();
РисуемГоризЛинии();
РисуемВертЛинии();
РисованиеЭпюры();
pictureBox1.Image = Растр;
Графика.Dispose();
}//
private void РисуемОси()
{
Pen Перо = new Pen(Color.Black, 2);
// Рисование вертикальной оси координат:
Графика.DrawLine(Перо, ОтступСлева, УГоризОси, ОтступСлева, ОтступСверху);
// Рисование горизонтальной оси координат:
Графика.DrawLine(Перо, ОтступСлева, УГоризОси, Хтах, УГоризОси);
for (int i = 1; i <= 10; i++)
{ // Рисуем "усики" на вертикальной координатной оси:
int У = УГоризОси - i * ВертШаг;
Графика.DrawLine(Перо, ОтступСлева - 5, У, ОтступСлева, У);
// Подписываем значения продаж через каждые 100 единиц:
Графика.DrawString((i * 100).ToString(), new Font("Arial", 8 Brushes.Black, 2, Y - 5);
}
// Подписываем месяцы на горизонтальной оси:
for (int i = 0; i <= Months.Length - 1; i++)
Графика.Drawstring(Months[i], new Font("Arial", 8), Brushes.Black,
ОтступСлева + 18 + (int)(i * ГоризШаг), УГоризОси + 4
} //
private void РисуемГоризЛинии()
{
Pen ТонкоеПеро = new Pen(Color.LightGray, 1);
for (int i = 1; i <= 10; i++)
{ // Рисуем горизонтальные почти "прозрачные" линии:
int У = УГоризОси - ВертШаг * i;
Графика .DrawLine (ТонкоеПеро, ОтступСлева + 3, У, Хтах, У);
}
ТонкоеПеро.Dispose();
} //
private void РисуемВертЛинии()
{ // Рисуем вертикальные почти "прозрачные" линии
Реп ТонкоеПеро = new Pen(Color.Bisque, 1);
for (int i = 0; i <= Months.Length - 1; i++)
{
int X = ХНачЭпюры + (int)(ГоризШаг * i);
Графика.DrawLine(ТонкоеПеро, X, ОтступСверху, X, УГоризОси – 4);
}
ТонкоеПеро.Dispose ();
} // „
private void РисованиеЭпюры()
{
double ВертМасштаб = (double)ДлинаВертОси / 1000;
int[] Y = new int[Sales.Length]; // значения ординат на экране
int[] X = new int[Sales.Length]; // значения абсцисс на экране
for (int i = 0; i <= Sales.Length - 1; i++)
{ // Вычисляем графические координаты точек:
Y[i] = УГоризОси - (int)(Sales[i] * ВертМасштаб);
// Отнимаем значения продаж, поскольку ось У экрана
// направлена вниз
X[i] = ХНачЭпюры + (int)(ГоризШаг * i);
}
// Рисуем первый кружок:
Реn Перо = new Pen(Color.Blue, 3);
Графика.DrawEllipse(Перо, Х[0] - 2, У[0] - 2, 4, 4);
for (int i = 0; i <= Sales.Length - 2; i++)
{ // Цикл no линиям между точками:
Графика.DrawLine(Перо, X[i], Y[i], X[i + 1], Y[i + 1]);
// Отнимаем 2, поскольку диаметр (ширина) точки = 4:
Графика.DrawEllipse(Перо, X[i + 1] - 2, Y[i + 1] - 2, 4, 4);
}
}
}
}
Как видно из текста программы, вначале объявляем некоторые переменные, чтобы они были видны из всех процедур класса. Строковый массив Months содержит названия месяцев, которые пользователь нашего программного кода может менять в зависимости от контекста строящегося графика. В любом случае записанные строки в этом массиве будут отображаться по горизонтальной оси графика. Массив целых чисел Sales содержит объемы продаж по каждому месяцу, они соответствуют вертикальным ординатам графика. Оба массива должны иметь между собой одинаковую размерность, но не обязательно равную двенадцати.
При обработке события "щелчок мыши на кнопке" Button создаем объект класса Graphics, используя элемент управления PictureBox, а затем, вызывая соответствующие процедуры, поэтапно рисуем координатные оси, сетку из горизонтальных и вертикальных линий и непосредственно эпюру. Чтобы успешно, минимальными усилиями, с возможностью дальнейшего совершенствования программы построить график, следует как можно более понятно назвать некоторые ключевые, часто встречающиеся интервалы и координаты на рисунке. Из названия этих интервалов будет следовать смысл. Скажем, переменная ОтступСлева хранит число пикселов, на которое следует отступать, чтобы строить на графике, например, вертикальную ось продаж. Кроме очевидных названий упомянем переменную