Аннотация: Печать содержимого 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 элемента PrintDocument — printDocument1. Тем самым мы связываем объект 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).
In this article, we will discuss how to print an entire Windows Form using Print Dialog & Print Preview tools in a Windows Forms application, step-by-step. It displays the actual printing page size and print area and print page type (single, double) in the the entire designed form.
Print Preview tool
It is an open tool and supports all the Visual Studio versions. We use this tool to show the print preview of the page. The PrintPreviewDialog is convenient and easy to use. All you need to do is to create an instance of the dialog class and assign your Print Document object to the Document property.
Print Dialog tool
This tool helps to print the dialog control that is used to open the Windows Print Dialog and lets the user select the printer and set printer, and paper properties to print a file.
Let’s begin.
Step 1. Click New >> Project >> Visual C# >> Windows >> Windows Forms Application. Enter your Project name and click OK.
Step 2. Click the View->Select Toolbox. We are using this Toolbox to design the Form in the Windows application and Add the Print (Button).
Step 3. In Toolbox, we have to add Print Dialog & Print Preview. Just Drag & Drop in the form.
Step 4. Double-click the Print Document properties and printDocument1_PrintPage to be completed for the event to make the function more accurate.
C# Code
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(bitmap, 0, 0);
}
Step 5. Double-click the Print button and button2_Click to be completed for the event to make the function more accurate.
Header File
using System.Drawing.Printing;
C# Code
private void button2_Click(object sender, EventArgs e)
{
Panel panel = new Panel();
this.Controls.Add(panel);
Graphics grp = panel.CreateGraphics();
Size formSize = this.ClientSize;
bitmap = new Bitmap(formSize.Width, formSize.Height, grp);
grp = Graphics.FromImage(bitmap);
Point panelLocation = PointToScreen(panel.Location);
grp.CopyFromScreen(panelLocation.X, panelLocation.Y, 0, 0, formSize);
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.PrintPreviewControl.Zoom = 1;
printPreviewDialog1.ShowDialog();
}
Bitmap bitmap;
private void CaptureScreen()
{
Graphics myGraphics = this.CreateGraphics();
Size s = this.Size;
bitmap = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(bitmap);
memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, s);
}
Step 6. At Runtime, the dialog will show generating previews like given below. It will show the time of printing also.
Step 7. Press F5 or «.Build and Run» the application.
Finally, we have successfully printed the entire Windows Forms application using the Print dialog and Print Preview.
Несомненно в языке C# и фреймворке .NET есть средства для печати документов и текста с помощью принтера. В данной статье описано, как вывести на печать текст программно. А для тех, кто больше любит смотреть, чем читать — в конце материла находится видеоурок по данной теме.
Печать на C# — Пошаговая инструкция
Создадим новый проект Windows Forms в Visual Studio.
Добавим на форму кнопку Button. Изменим ее свойство Text на значение «Печать». Имя кнопки в коде (Name) зададим равным «printButton».
Перейдем к коду на C# с помощью двойного щелчка мышью по кнопке «Печать» — тем самым будет создан обработчик события нажатия на данную кнопку.
В классе Form1 создадим поле типа string для хранения текста, который будем печатать на принтере.
private string result = «»; |
Подключим необходимое пространство имен.
using System.Drawing.Printing; |
Затем напишем обработчик события печати, который будет непосредственно отрисовывать текст на листе бумаги (по аналогии с отрисовкой строки на Bitmap). Шрифт укажем Arial, размер текста 14 пунктов, для отрисовки будем использовать черную кисть, а координаты (X; Y) начального положения укажем (0; 0).
void PrintPageHandler(object sender, PrintPageEventArgs e) { e.Graphics.DrawString(result, new Font(«Arial», 14), Brushes.Black, 0, 0); } |
Оставшийся код пишем в обработчике события нажатия кнопки Печать.
Укажем текст для печати.
result = «Строка 1\n\n»; result += «Строка 2\nСтрока 3»; |
Символы перехода на новую строку позволяют представить текст в следующем виде:
Теперь создадим объект для печати текста на C#.
PrintDocument printDocument = new PrintDocument(); |
Добавим в него наш обработчик события печати.
printDocument.PrintPage += PrintPageHandler; |
Создадим объект, реализующий диалоговое окно с настройкой печати (в котором можно выбирать принтер, указывать количество копий документа и пр.).
PrintDialog printDialog = new PrintDialog(); |
Установим в диалог печати сам документ для печати.
printDialog.Document = printDocument; |
Запускаем диалоговое окно для печати и если в нем была нажата кнопка ОК, то выполняем печать документа на принтере.
if (printDialog.ShowDialog() == DialogResult.OK) printDialog.Document.Print(); |
Полный код урока с комментариями — Печать на C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System; using System.Drawing; using System.Drawing.Printing; using System.Windows.Forms; namespace TestPrintProject { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // текст для печати private string result = «»; // обработчик события нажатия на кнопку Печать private void printButton_Click(object sender, EventArgs e) { // задаем текст для печати result = «Строка 1\n\n»; result += «Строка 2\nСтрока 3»; // объект для печати PrintDocument printDocument = new PrintDocument(); // обработчик события печати printDocument.PrintPage += PrintPageHandler; // диалог настройки печати PrintDialog printDialog = new PrintDialog(); // установка объекта печати для его настройки printDialog.Document = printDocument; // если в диалоге было нажато ОК if (printDialog.ShowDialog() == DialogResult.OK) printDialog.Document.Print(); // печатаем } // обработчик события печати void PrintPageHandler(object sender, PrintPageEventArgs e) { // печать строки result e.Graphics.DrawString(result, new Font(«Arial», 14), Brushes.Black, 0, 0); } } } |
Тестирование программы
Запустим программу, нажмем кнопку Печать и увидим следующее окно.
Результат печати представлен ниже.
Печать документов на C# — Видеоурок
In this article I will explain how to print the contents of Form in Windows Forms (WinForms) Application using C# and VB.Net.
The Form contents will be printed without the Form Header and Form borders.
Form Controls
In the below Form, there’s a DataGridView, a Print Button, a PrintPreviewDialog and a PrintDocument controls.
Populating DataGridView
In order to populate the DataGridView, I have created a dynamic DataTable with some sample data.
C#
private void Form1_Load(object sender, EventArgs e)
{
this.BindDataGridView();
}
private void BindDataGridView()
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn(«Id», typeof(int)),
new DataColumn(«Name», typeof(string)),
new DataColumn(«Country»,typeof(string)) });
dt.Rows.Add(1, «John Hammond», «United States»);
dt.Rows.Add(2, «Mudassar Khan», «India»);
dt.Rows.Add(3, «Suzanne Mathews», «France»);
dt.Rows.Add(4, «Robert Schidner», «Russia»);
this.dataGridView1.DataSource = dt;
}
VB.Net
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
BindDataGridView()
End Sub
Private Sub BindDataGridView()
Dim dt As New DataTable()
dt.Columns.AddRange(New DataColumn(2) {New DataColumn(«Id», GetType(Integer)), New DataColumn(«Name», GetType(String)), New DataColumn(«Country», GetType(String))})
dt.Rows.Add(1, «John Hammond», «United States»)
dt.Rows.Add(2, «Mudassar Khan», «India»)
dt.Rows.Add(3, «Suzanne Mathews», «France»)
dt.Rows.Add(4, «Robert Schidner», «Russia»)
Me.dataGridView1.DataSource = dt
End Sub
Printing the contents of Form
When the Print Button is clicked, first a Panel control is added to the Form. Then an object of the Graphic class is created from the Panel and its Height and Width is set to that of the Height and Width of the Form after excluding its Header and Borders.
Using the Graphics object, Bitmap object is created from the Panel and the Form area covered by the Panel is captured within it.
Finally the PrintPreviewDialog is shown and the Bitmap object is printed.
C#
Bitmap bitmap;
private void btnPrint_Click(object sender, EventArgs e)
{
//Add a Panel control.
Panel panel = new Panel();
this.Controls.Add(panel);
//Create a Bitmap of size same as that of the Form.
Graphics grp = panel.CreateGraphics();
Size formSize = this.ClientSize;
bitmap = new Bitmap(formSize.Width, formSize.Height, grp);
grp = Graphics.FromImage(bitmap);
//Copy screen area that that the Panel covers.
Point panelLocation = PointToScreen(panel.Location);
grp.CopyFromScreen(panelLocation.X, panelLocation.Y, 0, 0, formSize);
//Show the Print Preview Dialog.
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.PrintPreviewControl.Zoom = 1;
printPreviewDialog1.ShowDialog();
}
private void PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
//Print the contents.
e.Graphics.DrawImage(bitmap, 0, 0);
}
VB.Net
Private bitmap As Bitmap
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
‘Add a Panel control.
Dim panel As New Panel()
Me.Controls.Add(panel)
‘Create a Bitmap of size same as that of the Form.
Dim grp As Graphics = panel.CreateGraphics()
Dim formSize As Size = Me.ClientSize
bitmap = New Bitmap(formSize.Width, formSize.Height, grp)
grp = Graphics.FromImage(bitmap)
‘Copy screen area that that the Panel covers.
Dim panelLocation As Point = PointToScreen(panel.Location)
grp.CopyFromScreen(panelLocation.X, panelLocation.Y, 0, 0, formSize)
‘Show the Print Preview Dialog.
printPreviewDialog1.Document = printDocument1
printPreviewDialog1.PrintPreviewControl.Zoom = 1
printPreviewDialog1.ShowDialog()
End Sub
Private Sub PrintPage(sender As Object, e As System.Drawing.Printing.PrintPageEventArgs) Handles printDocument1.PrintPage
‘Print the contents.
e.Graphics.DrawImage(bitmap, 0, 0)
End Sub
Screenshots
Print Preview Dialog displaying the contents of the Form
Printed contents of Form
Downloads
Download Code
- Приложение Windows Forms печати текстовых файлов
- Печать на принтер
- События PrintDocument
- Особенности печати PrintPreviewDialog
- Печать из PrintDialog
- Модуль настроек печати
- Кодировка текстовых файлов
- Исходник приложения печати текстовых файлов
Статья описывает исходный код приложения C# Windows Forms печати текстовых файлов. Функциональность приложения включает выбор файла, принтера, настройки параметров печатаемой страницы, предварительный просмотр печати, изменение вида и цвета шрифта. Если в вашей системе Windows нет установленных принтеров печать можно осуществлять в файл pdf.
Для настроек и выполнения печати применены стандартные диалоговые окна Windows: PrintPreviewDialog, PrintDialog, PageSetupDialog. Для выбора шрифта и его цвета используются FontDialog и ColorDialog соответственно. Полный комплект данных для печати между диалогами сохраняется в экземпляре класса PrintDocument и поэтому он определен как глобальный на уровне класса.
Глобальные поля на уровне класса:
public partial class Form1 : Form
{
// переменная доступа к выбранному для печати файла.
private StreamReader? _printFile = null;
// Хранение настроек печатаемого документа.
private readonly PrintDocument _printDocument = new();
// Временное хранение пути к файлу выбранному для печати.
private string? _fileToPrint = null;
// Шрифт по умолчанию для печати
private Font _printFont = new("Arial", 10);
// Цветовая кисть по умолчанию для шрифта
private readonly SolidBrush _printColor = new(Color.Black);
...
}
Печать на принтер
Печать в C# Windows Forms представляет собой знакомую процедуру рисования в экземпляре класса Graphics, но с выводом нарисованного на устройство принтер. В отличие от вывода на экран, при формировании печати дополнительно необходимо писать программный код деления графики на страницы.
Для каждого вида файлов пишется отдельный программный код. Для текстовых файлов, для документов Word, Excel, PDF, для изображений и т. п. программные коды вывода на принтер заметно отличаются.
Кроме того, координаты расположения контента на экране и на бумаге принтера, как правило, не совпадают. Чтобы правильно расположить элементы графики на странице необходимо согласованное использование свойства Graphics.PageUnit и вычисления координат, размеров печатаемых элементов.
GraphicsUnit.Display — определяет единицу измерения 1/100 дюйма для принтеров.
GraphicsUnit.Millimeter — определяет миллиметр в качестве единицы измерения.
GraphicsUnit.Inch — задает дюйм в качестве единицы измерения.
GraphicsUnit.Point — определяет точку для принтера, размером 1/72 дюйма, в качестве единицы измерения.
GraphicsUnit.Document — указывает единицу измерения документа (1/300 дюйма) в качестве единицы измерения.
По умолчанию для печати Graphics.PageUnit содержит значение Display, определяющее единицу измерения 1/100 дюйма равную 254 мкм (называется калибр, применяется в США и Великобритании, калибр численно равен точке в старой русской системе мер).
Примечание. Работая с дюймами обязательно указывайте для чисел тип float 100.0f (но не 100), поскольку в ином случае возможна потеря точности расположения элементов на странице.
Краткий программный код согласования координат и размеров элементов для бумаги (страницы) А4 в зависимости от выбранной PageUnit, полный код смотрите ниже в событии PrintDocument.PrintPage:
graphics.PageUnit = GraphicsUnit.Display;
//graphics.PageUnit = GraphicsUnit.Point;
//graphics.PageUnit = GraphicsUnit.Millimeter;
//graphics.PageUnit = GraphicsUnit.Inch;
// Счетчик строк
int counterLines = 0;
// Строка текста
string? lineText = null;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
// Высота шрифта в выбранных единицах объекта graphics.
float fontHeight = _printFont.GetHeight(graphics);
// Количество возможных строк для одной страницы.
float linesPerPage = e.MarginBounds.Height / fontHeight;
Pen rectPen = new(Brushes.Red)
{
Alignment = System.Drawing.Drawing2D.PenAlignment.Inset
};
switch (graphics.PageUnit)
{
case GraphicsUnit.Display:
// Ширина пера 1мм
rectPen.Width = (1 * 100.0f) / 25.4f;
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f * 100.0f, 11.69291338582677f * 100.0f);
break;
case GraphicsUnit.Point:
// Ширина пера 1мм
rectPen.Width = (1 * 72.0f) / 25.4f;
linesPerPage =
(e.MarginBounds.Height * (72.0f / 100.0f)) / fontHeight;
leftMargin = e.MarginBounds.Left * (72.0f / 100.0f);
topMargin = e.MarginBounds.Top * (72.0f / 100.0f);
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f * 72.0f, 11.69291338582677f * 72.0f);
break;
case GraphicsUnit.Millimeter:
// Ширина пера 1мм
rectPen.Width = 1;
linesPerPage =
(e.MarginBounds.Height * (25.4f / 100.0f)) / fontHeight;
leftMargin = e.MarginBounds.Left * (25.4f / 100.0f);
topMargin = e.MarginBounds.Top * (25.4f / 100.0f);
graphics.DrawRectangle(rectPen, 0, 0, 210, 297);
break;
case GraphicsUnit.Inch:
// Ширина пера 1мм
rectPen.Width = 1 / 25.4f;
linesPerPage =
(e.MarginBounds.Height / 100.0f) / fontHeight;
leftMargin = e.MarginBounds.Left / 100.0f;
topMargin = e.MarginBounds.Top / 100.0f;
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f, 11.69291338582677f);
break;
}
// Печать последовательно всех строк файла на одной странице.
while (counterLines < linesPerPage &&
((lineText = _printFile.ReadLine()) != null))
{
// Координата позиции строки по высоте от верхнего края страницы.
float yPos = topMargin + (counterLines * fontHeight);
//
graphics.DrawString(
lineText,
_printFont,
_printColor,
leftMargin,
yPos
);
//
counterLines++;
}
События PrintDocument
Для облегчения программирования печати C# Windows Forms предоставляет высокоуровневый класс PrintDocument, хранящий в себе все параметры печати и способный распечатать документ на принтере по умолчанию. PrintDocument имеет в своем составе события, генерирующиеся перед печатью, при отправке страницы на печать и после окончания печати последней страницы.
События PrintDocument.BeginPrint и PrintDocument.EndPrint возникают в начале и в конце печати. BeginPrint и EndPrint предназначены для подготовки ресурсов (например, файла) для печати и освобождение ресурсов после печати соответственно.
Событие PrintDocument.PrintPage возникает при отправке каждой страницы на печать. В обработчике события PrintPage(object sender, PrintPageEventArgs e)
происходит подготовка контента для печати на одну страницу, в случае если контент не поместился на одну страницу, в обработчике обеспечивается оповещение PrintPageEventArgs.HasMorePages=true
о необходимости печати следующей страницы.
Ниже программный код обработчиков событий BeginPrint, PrintPage, EndPrint приложения печати текстовых файлов. Если выбирать различные единицы измерения для Graphics.PageUnit, логика соответствующего кода скорректирует координаты и размеры. Для большей наглядности по периметру страницы, для всех единиц измерения, печатается красная рамка толщиной в 1 мм.
// Вызывается перед печатью страниц.
private void PrintDocument_BeginPrint(object sender, PrintEventArgs e)
{
// Перед печатью открываем выбранный файл.
if (_fileToPrint != null)
{
_printFile = new StreamReader(
_fileToPrint,
Encoding.GetEncoding(comboBox1.Text));
}
else e.Cancel = true;
}
// Вызывается после окончания печати всех страниц.
private void PrintDocument_EndPrint(object sender, PrintEventArgs e)
{
// Закрываем файл после окончания печати.
_printFile?.Close();
}
// Событие объекта класса PrintDocument,
// вызывается для рисования-печати каждой страницы.
private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
if (_printFile != null && e.Graphics is Graphics graphics)
{
graphics.PageUnit = GraphicsUnit.Display;
//graphics.PageUnit = GraphicsUnit.Point;
//graphics.PageUnit = GraphicsUnit.Millimeter;
//graphics.PageUnit = GraphicsUnit.Inch;
// Счетчик строк
int counterLines = 0;
// Строка текста
string? lineText = null;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
// Высота шрифта в выбранных единицах объекта graphics.
float fontHeight = _printFont.GetHeight(graphics);
// Количество возможных строк для одной страницы.
float linesPerPage = e.MarginBounds.Height / fontHeight;
Pen rectPen = new(Brushes.Red)
{
Alignment = System.Drawing.Drawing2D.PenAlignment.Inset
};
switch (graphics.PageUnit)
{
case GraphicsUnit.Display:
// Ширина пера 1мм
rectPen.Width = (1 * 100.0f) / 25.4f;
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f * 100.0f, 11.69291338582677f * 100.0f);
break;
case GraphicsUnit.Point:
// Ширина пера 1мм
rectPen.Width = (1 * 72.0f) / 25.4f;
linesPerPage =
(e.MarginBounds.Height * (72.0f / 100.0f)) / fontHeight;
leftMargin = e.MarginBounds.Left * (72.0f / 100.0f);
topMargin = e.MarginBounds.Top * (72.0f / 100.0f);
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f * 72.0f, 11.69291338582677f * 72.0f);
break;
case GraphicsUnit.Millimeter:
// Ширина пера 1мм
rectPen.Width = 1;
linesPerPage =
(e.MarginBounds.Height * (25.4f / 100.0f)) / fontHeight;
leftMargin = e.MarginBounds.Left * (25.4f / 100.0f);
topMargin = e.MarginBounds.Top * (25.4f / 100.0f);
graphics.DrawRectangle(rectPen, 0, 0, 210, 297);
break;
case GraphicsUnit.Inch:
// Ширина пера 1мм
rectPen.Width = 1 / 25.4f;
linesPerPage =
(e.MarginBounds.Height / 100.0f) / fontHeight;
leftMargin = e.MarginBounds.Left / 100.0f;
topMargin = e.MarginBounds.Top / 100.0f;
graphics.DrawRectangle(
rectPen,
0, 0,
8.267716535433071f, 11.69291338582677f);
break;
}
// Печать последовательно всех строк файла на одной странице.
while (counterLines < linesPerPage &&
((lineText = _printFile.ReadLine()) != null))
{
// Координата позиции строки по высоте от верхнего края страницы.
float yPos = topMargin + (counterLines * fontHeight);
//
graphics.DrawString(
lineText,
_printFont,
_printColor,
leftMargin,
yPos
);
//
counterLines++;
}
// Если текст еще остался, печатаем следующую страницу.
if (lineText != null)
{
e.HasMorePages = true;
}
else
{
// Печать закончена
e.HasMorePages = false;
}
}
}
Особенности печати PrintPreviewDialog
PrintPreviewDialog – диалоговое окно печати с предпросмотром будущих страниц. Имеет свойства стандартного диалогового окна, с отличительным программным свойством PrintDocument, по данным которого создается предпросмотр страниц в актуальных координатах и возможность отправки печати на принтер.
Примечание. Работая с предварительным просмотром печати в PrintPreviewDialog необходимо учитывать, что при открытии диалога происходит полноценная печать всех страниц в окно PrintPreviewDialog. Нажатие на кнопку печать – это уже повторная печать, и если не предусмотреть повторную инициализацию ресурсов печати, то в результате на принтере будет распечатываться пустая страница.
Печать из PrintDialog
PrintDialog – диалог настроек принтера и печати: выбор принтера, установка диапазона печати, количество копий, сброс настроек и другое в зависимости от моделей принтеров.
PrintDialog наследует от CommonDialog возможность показа кнопки Справка и события нажатия данной кнопки. В обработчике события программистом пишется код формирования и вызова окна со справочной информацией.
Программный код исполнения печати из разных диалогов. Объект PrintDialog показан с обработчиком события вызова справки:
private void BtnPreviewPrint_Click(object sender, EventArgs e)
{
// Предварительный просмотр печати
PrintPreviewDialog dialog = new()
{
Document = _printDocument
};
dialog.ShowDialog();
}
private void BtnPrintDialog_Click(object sender, EventArgs e)
{
PrintDialog dialog = new()
{
Document = _printDocument,
// Показывать кнопку Справка
ShowHelp = true,
// Выбор печатаемых страниц
AllowSomePages = true,
// Вид окна печати в стиле Windows XP.
//UseEXDialog = true
};
// Определение обработчика вызова справки.
dialog.HelpRequest += PrintDialog_HelpRequest;
if (dialog.ShowDialog() == DialogResult.OK)
{
_printDocument.Print();
}
}
// Вызов окна справки для PrintDialog
private void PrintDialog_HelpRequest(object? sender, EventArgs e)
{
MessageBox.Show("Справка диалога печати!");
}
private void BtnPrintDocument_Click(object sender, EventArgs e)
{
_printDocument.Print();
}
Модуль настроек печати
Настройки параметров страницы, выбор шрифта печати и его цвета выделены в отдельный условный модуль. При изменении пользователем параметров страницы, данные сохраняются в объекте класса PrintDocument.
Программный код модуля настроек печати:
#region Настройка печати
private void BtnPageSetup_Click(object sender, EventArgs e)
{
PageSetupDialog dialog = new()
{
// В .NET Framework версии 2.0 и выше вы должны
// установить для этого свойства значение true
// если ваше приложение может использоваться в культурах,
// которые измеряют поля документа в миллиметрах.
EnableMetric = true,
Document = _printDocument
};
dialog.ShowDialog();
}
private void BtnSelectFont_Click(object sender, EventArgs e)
{
FontDialog dialog = new()
{
Font = _printFont
};
if (dialog.ShowDialog() == DialogResult.OK)
{
_printFont = dialog.Font;
}
}
private void BtnFontColor_Click(object sender, EventArgs e)
{
ColorDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{
_printColor.Color = dialog.Color;
}
}
#endregion
Кодировка текстовых файлов
По умолчанию, на платформе .NET Core применяется кодировка UTF-8 для текстовых файлов. Кроме того, .NET Core, в отличие от .NET Framework, поддерживает небольшое количество кодировок. Класс CodePagesEncodingProvider расширяет количество доступных кодировок для .NET Core.
Для случаев распечатывания текстовых файлов со специфическими кодировками в описываемом приложении предусмотрено изменение кодировки чтения для выбранного файла.
Программный код определения доступа к дополнительным кодировкам:
public Form1()
{
InitializeComponent();
// Расширяет доступ к кодировкам, которые недоступны в .NET
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// Заполнение комбинированного бокса доступными кодировками.
foreach (EncodingInfo en in Encoding.GetEncodings())
{
comboBox1.Items.Add(en.Name);
}
comboBox1.Sorted = true;
...
}
Исходник приложения печати текстовых файлов
Статья может описывать не весь исходный код, но для случаев заинтересованного изучения приложения печати к статье прикрепляется архивный рабочий файл исходника. Исходный код приложения написан на языке C# в MS Visual Studio 2022, платформа .NET6, Windows Forms.
Скачать исходник
Тема: «Печать текстовых файлов»
WinFormsAppPrint-vs17.zip
Размер:88 КбайтЗагрузки:263