C#. Windows Forms. Практика. Створення документу для роздруку. Елементи управління 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. Програмування обробника події кліку на кнопці “Print Preview”

 

// Команда PrintPreviewDialog()
private void button3_Click(object sender, EventArgs e)
{
  printPreviewDialog1.ShowDialog();
}

 

7. Запуск програми на виконання

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

 


Зв’язані теми