C#. Практика. Создание документа для печати. Элементы управления PrintDocument, PageSetupDialog, PrintDialog, PrintPreviewDialog




Создание документа для печати. Элементы управления PrintDocument, PageSetupDialog, PrintDialog, PrintPreviewDialog

В данной теме продемонстрированы средства печати документов для программ, написанных по шаблону Windows Forms на языке программирования C#.


Содержание


Поиск на других ресурсах:

Теоретические сведения

Для обеспечения печати, в .NET Framework реализованы специальные классы, базовыми из которых есть:

  • PrintDocument – представляет класс, объект которого посылает данные на принтер;
  • PageSetupDialog – представляет диалоговое окно, которое позволяет пользователю изменять настройки страницы для печати (внутренние поля, ориентация печати, и т.п.);
  • PrintDialog – представляет диалоговое окно, которое позволяет пользователю выбирать принтер и прочие настройки принтера, такие как количество копий, ориентация страницы и т.п.;
  • PrintPreviewDialog – представляет диалоговое окно, которое показывает пользователю предыдущий просмотр документа в том виде как он будет отображен при печати.

 

Условие задачи

Разработать приложение типа Windows Forms, который распечатывает информацию содержащуюся в элементе управления RichTextBox. Приложение должно содержать команды:

  • печать документа;
  • предварительный просмотр документа;
  • настройка страниц в документе.

В программе использовать элементы управления PrintDocument, PageSetupDialog, PrintDialog, PrintPreviewDialog.

 

Выполнение

1. Создать проект

После создания проекта создается пустая форма. Класс формы называется Form1.

 

2. Разработка формы. Размещение элементов управления на форме

Разработать главную форму программы как изображено на рисунке 1.

C#. Windows Forms. Программа печати документа. Главная форма

Рисунок 1. Главная форма программы

На форме нужно разместить следующие элементы управления:

  • элемент управления типа Label. Создается экземпляр с именем label1;
  • три элемента управления типа Button. Будут созданы экземпляры с именами button1, button2, button3;
  • элемент управления типа RichTextBox. Создается экземпляр с именем richTextBox1;
  • элемент управления типа PrintDocument. Создается экземпляр с именем printDocument1. Этот элемент управления представляет документ, который будет распечатан;
  • элемент управления типа PageSetupDialog. Создается экземпляр с именем pageSetupDialog1;
  • элемент управления типа PrintDialog. Создается экземпляр с именем printDialog1;
  • элемент управления типа PrintPreviewDialog. Создается экземпляр с именем printPreviewDialog1.

Размещение элементов управления PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewDialog изображено на рисунке 2.

C#. Windows Forms. Элементы управления PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewDialog

Рисунок 2. Элементы управления PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewDialog

 

3. Настройка базовых визуальных элементов управления на форме

На этом этапе нужно настроить свойства элементов управления формы следующим образом:
– в элементе управления Form1 свойство Text = «Print document»;
– в label1 свойство Text = «Specified text:» (label1.Text = «Specified text:»);
button1.Text = «Page Setup»;
button2.Text = «Print»;
button3.Text = «Print Preview».

После настройки форма будет иметь вид, как изображено на рисунке 1.

 

4. Настройка элементов управления PageSetupDialog, PrintDialog, PrintPreviewDialog, PrintDocument

Следующим шагом нужно связать элементы управления pageSetupDialog1, printDialog1, printPreviewDialog1 с документом printDocument1. Для этого используется свойство Document. Настройки выглядят следующим образом:
pageSetupDialog1.Document = printDocument1 (рисунок 3);
printDialog1.Document = printDocument1;
printPreviewDialog1.Document = printDocument1;
printDialog1.AllowSomePages = True. Это свойство разрешает или запрещает кнопку настройки страницы в окне печати.

C#. Windows Forms. Элемент управления pageSetupDialog1. Свойство Document = printDocument1

Рисунок 3. Элемент управления pageSetupDialog1. Свойство Document = printDocument1

 



5. Ввод дополнительных переменных в класс формы

Согласно условию задачи, нужно распечатать текст, который набран в элементе управления richTextBox1. При печати нужно сохранять номер строки в richTextBox1, которая на данный момент печатается. Для обеспечения этого в класс формы Form1 вводится дополнительная переменная counter.
Также вводится переменная curPage, определяющая страницу, которая печатается на данный момент.

Фрагмент текста класса формы Form1 следующий

...

public partial class Form1 : Form
{
  // Количество выделенных строк:
  // 0 <= counter <= richTextBox1.Lines.Length
  int counter = 0; // сквозной номер строки в массиве строк, которые выводятся
  int curPage; // текущая страница

  ...

}

...

 

6. Программирование обработчиков событий
6.1. Основные события, обеспечивающие печать документа

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

  • BeginPrint – это событие возникает перед самым началом печати документа. В обработчик этого события целесообразно вписывать код инициализации внутренних переменных, которые руководят печатью документа;
  • PrintPage – возникает один раз при печати каждой страницы. Например, если печатается 5 страниц, то это событие возникнет 5 раз;
  • EndPrint – возникает, после печати документа;
  • QueryPageSetting – возникает прежде чем каждая страница должна быть напечатана. Перехват этого события полезен в случаях, когда нужно изменить настройки конкретной печатаемой страницы.

 

6.2. Программирование обработчика события BeginPrint компонента printDocument1

Первым программируется событие BeginPrint элемента управления printDocument1. Чтобы получить обработчик этого события, нужно выбрать элемент управления printDocument1 и в перечне событий выбрать событие BeginPrint (двойной клик мышкой).
В нашем случае, в обработчике события BeginPrint нужно реализовать инициализацию переменных counter и curPage

// Начало печати
private void printDocument1_BeginPrint(object sender,
    System.Drawing.Printing.PrintEventArgs e)
{
  // Перед началом печати переменные-счетчики
  // установить в начальные значения
  counter = 0;
  curPage = 1;
}

 

6.3. Программирование обработчика события PrintPage компонента printDocument1

Основной программный код, выполняющий вывод на принтер, реализован в обработчике события PrintPage. Текст обработчика следующий:

// Обработчик события PrintPage - здесь нужно программировать печать
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
  // Создать шрифт myFont
  Font myFont = new Font("Arial", 14, FontStyle.Regular, GraphicsUnit.Pixel);

  string curLine; // текущая выводимая строка

  // Отступы внутри страницы
  float leftMargin = e.MarginBounds.Left; // отступы слева в документе
  float topMargin = e.MarginBounds.Top; // отступы сверху в документе
  float yPos = 0; // текущая позиция Y для вывода строки

  int nPages; // количество страниц
  int nLines; // максимально-возможное количество строк на странице
  int i; // номер текущей строки для вывода на странице

  // Вычислить максимально возможное количество строк на странице
  nLines = (int)(e.MarginBounds.Height / myFont.GetHeight(e.Graphics));

  // Вычислить количество страниц для печати
  nPages = (richTextBox1.Lines.Length - 1) / nLines + 1;

  // Цикл печати/вывода одной страницы
  i = 0;
  while ((i < nLines) && (counter < richTextBox1.Lines.Length))
  {
    // Взять строку для вывода из richTextBox1
    curLine = richTextBox1.Lines[counter];

    // Вычислить текущую позицию по оси Y
    yPos = topMargin + i * myFont.GetHeight(e.Graphics);

    // Вывести строку в документ
    e.Graphics.DrawString(curLine, myFont, Brushes.Blue,
      leftMargin, yPos, new StringFormat());

    counter++;
    i++;
  }

  // Если весь текст не помещается на 1 страницу, то
  // нужно добавить дополнительную страницу для печати
  e.HasMorePages = false;

  if (curPage < nPages)
  {
    curPage++;
    e.HasMorePages = true;
  }
}

Объясним некоторые фрагменты кода в обработчике.
На основе размера заданного шрифта myFont и высоты страницы e.MarginBounds.Height определяется количество строк nLines, которые может вместить одна страница. Страниц может быть несколько. Номер текущей страницы определяется во внутренний переменной curPage, которая была описана в п. 5.
На основании количества строк на странице nLines и общего количества выводимых строк richTextBox1.Lines.Length, вычисляется общее количество страниц печати nPages.

В цикле while фигурирует два счетчика: счетчик страницы i и счетчик сквозной строки вывода counter (см. п. 5). Как только один из счетчиков принимает свое максимальное значение, происходит выход из цикла.

Также, в цикле в переменной yPos формируется координата y вывода текста по формуле. Вывод строки с текстом осуществляется с помощью метода

// Вывести строку в документ
e.Graphics.DrawString(curLine, myFont, Brushes.Blue,
    leftMargin, yPos, new StringFormat());

где

  • e – экземпляр типа PrintPageEventArgs, обеспечивающий необходимые данные для события PrintPage. С помощью этих данных можно управлять печатью документа;
  • e.Graphics – класс, который предназначен для рисования на странице. Кроме текста можно выводить любые графические примитивы;
  • e.Graphics.DrawString() – метод, который выводит определенную строку (curLine) в определенной позиции (leftMargin, yPos). Строка выводится шрифтом myFont и цветом Brushes.Blue.

В методе e.Graphics.DrawString() задается необязательный формат вывода типа StringFormat с помощью вызова

new StringFormat()

После цикла while происходит определение того, нужно ли генерировать следующую страницу

...

// сначала принять, что следующая страница не генерируется
e.HasMorePages = false;

if (curPage < nPages) // Если это не последняя страница
{
  curPage++;
  e.HasMorePages = true; // тогда нужно сгенерировать новую страницу
}

...

Значение e.HasMorePages отвечает за генерирование следующей страницы. Если e.HasMorePages=true то следующая страница генерируется. В противном случае следующая страница не генерируется, а это значит, что текущая страница есть последней. В программе происходит сравнение значения curPage (текущая страница) с общим количеством страниц nPages. Если значения curPage и nPages равны, то e.HasMorePages становится равным false и печать (просмотр) страниц прекращается.

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

 

6.4. Программирование обработчика события клика на кнопке «Page Setup»

Если пользователь сделал клик на кнопке «Page Setup», то должно открыться окно настройки параметров страницы.

// Команда Page Setup
private void button1_Click(object sender, EventArgs e)
{
  pageSetupDialog1.ShowDialog(); // отобразить окно
}

 

6.5. Программирование обработчика события клика на кнопке «Print»

Непосредственно печать документа осуществляется с помощью метода Print(), который вызывается из экземпляра printDocument1. Предварительно выводится диалоговое окно печати.

// Команда Print()
private void button2_Click(object sender, EventArgs e)
{
  if (printDialog1.ShowDialog() == DialogResult.OK)
    printDocument1.Print();
}

 

6.6. Программирование обработчика события клика на кнопке «PrintPreview»
// Команда PrintPreviewDialog()
private void button3_Click(object sender, EventArgs e)
{
  printPreviewDialog1.ShowDialog();
}

 

7. Запуск программы на выполнение

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

 


Связанные темы