Опубликован: 11.09.2006 | Уровень: специалист | Доступ: платный
Лекция 6:

Работа с печатью и изображениями

Аннотация: Печать содержимого RichTextBox. Элементы управления PrintDocument, PageSetupDialog, PrintPreviewDialog, PrintDialog. Работа с изображениями. Печать содержимого PictureBox. Рисование в Windows-формах. Элемент управления TrackBar. Автоматическое преобразование размера и прокручивание изображения. Создание собственных свойств пользовательского (композитного) элемента управления

Для работы с данной лекцией используйте примеры.

Тема печати в Windows традиционно относится к одной из самых сложных: наличие огромного количества параметров, свойств и методов делает эту довольно простую вещь сильно запутанной. В этой лекции мы рассмотрим такие несложные задачи, как настройка параметров страницы, предварительный просмотр, печать содержимого элемента RichTextBox, а также преобразование форматов и печать рисунков, помещенных в PictureBox. Элемент PictureBox поддерживает различные режимы просмотра изображений – мы применим их всех и создадим простое приложение, позволяющее просматривать фотографии. Мы также еще раз создадим пользовательский элемент управления с собственными свойствами.

Печать содержимого RichTextBox. Элементы управления PrintDocument, PageSetupDialog, PrintPreviewDialog, PrintDialog

В качестве исходного приложения, в котором будем реализовывать возможность печати, возьмем проект TextEditor, созданный нами во второй лекции. Как мы знаем, максимальный объем элемента TextBox ограничивается 64 Кб, для работы с многостраничными документами этого явно мало. Поэтому удаляем с формы элемент txtBox и на его место помещаем элемент RichTextBox, которому задаем имя rtbText. Свойству Dock устанавливаем значение Fill, кроме того, удаляем значение свойства Text. Изменяем и добавляем следующие пункты главного меню (рис. 6.1):

Name Text Shortcut
mnuFile &Файл
mnuOpen &Открыть CtrlO
mnuSave &Сохранить CtrlS
menuItem1 -
mnuPageSetup Пара&метры страницы
mnuPrintPreview Пред&варительный просмотр
mnuPrint &Печать CtrlP
Пункты главного меню

Рис. 6.1. Пункты главного меню

Перетаскиваем на форму из окна ToolBox элементы управления: PrintDocument, PageSetupDialog, PrintPreviewDialog и PrintDialog. Подобно другим элементам диалогов, они отображаются на панели компонент в среде Visual Studio .NET. При печати формируется одна или несколько страниц, за которые отвечает объект PrintDocument. Элементы управления PageSetupDialog, PrintPreviewDialog и PrintDialog представляют собой диалоговые окна параметров страниц, предварительного просмотра и печати соответственно. Настройка свойств этих объектов представляет собой столь гибкую и широкую задачу, решаемую в коде приложения, что, в отличие, например, от элементов OpenFileDialog или SaveFileDialog, имеет смысл создавать их программно, в классе формы:

// PrintDocument printDocument1 = new PrintDocument();
// PageSetupDialog  pageSetupDialog1 = new PageSetupDialog();
// PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
// PrintDialog printDialog1 = new PrintDialog();

Этот фрагмент полностью аналогичен добавлению на форму элементов. Мы, однако, будем использовать визуальный режим.

Свойству Document элементов управления PageSetupDialog и PrintPreviewDialog устанавливаем значение свойства Name элемента PrintDocumentprintDocument1. Тем самым мы связываем объект printDocument1, отвечающий за формирование страниц печати, с диалоговыми окнами. Устнавливаем следующие свойства элемента PrintDialog:

printDialog1, свойство Значение Описание
AllowSelection True Разрешение на печать выделенного фрагмента документа
AllowSomePages True Разрешение на печать нескольких страниц
PrintDocument printDocument1 Связывание с экземпляром объекта PrintDocument

На информационной панели окна Properties при выборе свойств AllowSelection или AllowSomePages можно заметить сообщение – Enables and disables the Selection/Pages radio button (Включает или отключает доступность радиопереключателей "Выделенный фрагмент/Страницы"). Само по себе определение этих свойств еще не включает соответствующую функциональность — еще одна причина, по которой конфигурировать объекты печати лучше программно:

InitializeComponent();
// pageSetupDialog1.Document = printDocument1;
// printPreviewDialog1.Document = printDocument1;
// printDialog1.Document = printDocument1;
// printDialog1.AllowSomePages = true;
// printDialog1.AllowSelection = true;

Переходим в код формы. Для работы с печатью в библиотеке .NET Framework применяется класс System.Drawing.Printing, поэтому его нужно подключить в самом начале работы:

using System.Drawing.Printing;

В классе формы объявляем следующие переменные:

//Переменная для хранения текста для печати.
//В нее мы будем помещать текст из RichTextBox
string stringPrintText;
//Переменная, определяющая номер страницы, с которой нужно начать печать
int StartPage;
//Переменная, определяющая количество страниц для печати:
int NumPages;
//Переменная, определяющая номер текущей страницы:
int PageNumber;
Листинг 6.1.

Следует обратить внимание на переменную stringPrintText — именно она будет отвечать за передачу текста в объект печати. Поскольку мы определили для нее строковый тип, это означает, что мы не сможем вывести на печать рисунки в тексте — как мы знаем, элемент RichTextBox поддерживает их наличие (в этом можно убедиться, скопировав содержимое документа Microsoft Word в наше приложение). Определение полной печати будет более сложным, что, впрочем, не является существенным для понимания самой концепции печати 11За ответом на этот вопрос я отправляю читателя к библиотеке MSDN. Если вы поймете общую идею, то без труда сможете нарастить дополнительные возможности на приложение для печати..

В конструкторе форме определяем диапазон страниц для печати:

public Form1()
  {
      
    InitializeComponent();
    …
    //Определяем номер страницы, с которой следует начать печать
    printDialog1.PrinterSettings.FromPage = 1;
    //Определяем максимальный номер печатаемой страницы.
    printDialog1.PrinterSettings.ToPage = printDialog1.PrinterSettings.MaximumPage;
  }
Листинг 6.2.

Максимальное количество страниц в диапазоне — 9999;, очевидно, что его вполне хватит для распечатки любого документа. Основным событием, в обработчике которого практически и будет осуществляться вся печать, будет событие PrintPage элемента printDocument1. Переключаемся в режим дизайна, выделяем элемент и, переключившись в окне Properties на вкладку событий, дважды щелкаем в поле этого события:

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
 {
    
 }
Листинг 6.3.

Далее все описываемые фрагменты кода будут относиться к этому обработчику.

Класс Graphics, принадлежащий пространству имен System.Drawing, — один из важнейших классов, отвечающих за рисование графики и вывода текста на форме. При создании новой формы пространство имен System.Drawing по умолчанию включается в шаблон. Для формирования страницы печати создаем экземпляр этого класса:

Graphics graph = e.Graphics;
//Создаем объект font, которому устанавливаем 
// шрифт элемента rtbText
Font font = rtbText.Font;
//Получаем значение межстрочного интервала — высоту шрифта 
float HeightFont = font.GetHeight(graph); 
//Создаем экземпляр strfmt класса StringFormat для определения 
//дополнительных параметров форматирования текста.
StringFormat  stringformat = new StringFormat();

Страница представляет собой прямоугольный объект, параметры которого следует определить. Для этого используется класс RectangleF (буква F указывает на использование типа данных с плавающей точкой float ):

//Создаем экземляры  rectanglefFull и rectfText класса RectangleF для 
//определения областей печати и текста. 
RectangleF rectanglefFull, rectfText;
//Создаем переменные для подсчета числа символов и строк.
int NumberSymbols, NumberLines;

Страница, формируемая для печати, состоит из трех областей (рис. 6.2).

Области страницы, выводимой на печать

увеличить изображение
Рис. 6.2. Области страницы, выводимой на печать
Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000