Create a Document Programmatically
A WPF application often produces documents that nobody types: a report built from figures, a confirmation or a cover letter. ServerTextControl builds such a document in code with the same building blocks a user has in the editor, formatted paragraphs, a table, an image and a page header, without touching the document in the editor. In a few steps, a button of your window creates a short quarterly report, writes it to a DOCX file and opens it in the TextControl of the window.
Prerequisites
- The application from Create Your First WPF Application, with a
TextControlnamedtextControl1in MainWindow.xaml. - An image file named logo.png in the project. In its properties, set Build Action to Content and Copy to Output Directory to Copy if newer, so that the file is next to the application when it runs.
Add a button to the DockPanel of MainWindow.xaml, before the TextControl element, so that it docks above the editor:
<Button x:Name="createButton" DockPanel.Dock="Top" Content="Create Report"
Click="createButton_Click" />
How Code Builds a Document
A ServerTextControl holds a document in memory and has no user interface. Your code writes into it at the current input position, the way typing does: its Selection sets the formatting of the next text and inserts it, and tables and images are inserted at the same position. Every insertion moves the input position behind the new content, so the document grows in the order in which the code runs.
The component itself is described in ServerTextControl in the Overview.
Build the Document
Replace the content of MainWindow.xaml.cs with the following code, keeping the namespace of your project:
using System.Windows;
using TXTextControl;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void createButton_Click(object sender, RoutedEventArgs e)
{
byte[] document;
using (ServerTextControl tx = new ServerTextControl())
{
// Initialize the new instance before using it
tx.Create();
// Title: Arial, 24 pt, bold, centered
tx.Selection.FontName = "Arial";
tx.Selection.FontSize = 480; // 480 twips = 24 pt
tx.Selection.Bold = true;
tx.Selection.ParagraphFormat = new ParagraphFormat()
{
Alignment = TXTextControl.HorizontalAlignment.Center
};
tx.Selection.Text = "Quarterly Report\r\n";
// Body text: 12 pt, not bold, left-aligned
tx.Selection.FontSize = 240; // 240 twips = 12 pt
tx.Selection.Bold = false;
tx.Selection.ParagraphFormat = new ParagraphFormat()
{
Alignment = TXTextControl.HorizontalAlignment.Left
};
tx.Selection.Text = "Sales by region for the second quarter.\r\n";
// A table of 4 rows and 3 columns with the ID 10
tx.Tables.Add(4, 3, 10);
TXTextControl.Table table = tx.Tables.GetItem(10);
TXTextControl.TableRow headerRow = table.Rows.GetItem(1);
headerRow.IsHeader = true;
headerRow.CellFormat = new TableCellFormat()
{
BackColor = System.Drawing.Color.LightSteelBlue
};
foreach (TXTextControl.TableCell cell in table.Cells)
{
cell.Text = $"R{cell.Row} C{cell.Column}";
}
// Text and a logo below the table
tx.Selection.Text = "Source: sales department.\r\n";
TXTextControl.Image logo = new TXTextControl.Image("logo.png", 4); // 4 = PNG
tx.Images.Add(logo, -1); // -1 = at the input position
// A header that repeats on every page
tx.HeadersAndFooters.Add(HeaderFooterType.Header);
HeaderFooter header = tx.HeadersAndFooters.GetItem(HeaderFooterType.Header);
header.Selection.Text = "Sample Company Inc.";
// A DOCX file, and a byte array for the editor
tx.Save("report.docx", StreamType.WordprocessingML);
tx.Save(out document, BinaryStreamType.InternalUnicodeFormat);
}
// Show the report in the editor of the window
textControl1.Load(document, BinaryStreamType.InternalUnicodeFormat);
}
}
What the Code Does
- Initializing. Create has to be called before any other member of the
ServerTextControl. Theusingstatement releases the instance as soon as the report is saved. - Formatting text. FontName, FontSize and Bold set the character formatting, and ParagraphFormat with its Alignment the paragraph formatting. Both apply to the text that the next assignment to Selection.Text inserts. Font sizes are in twips, 20 twips per point, and
\r\nends a paragraph. - Qualified names. WPF has types of the same name:
HorizontalAlignmentinSystem.WindowsandImageinSystem.Windows.Controls. WriteTXTextControl.HorizontalAlignmentandTXTextControl.Imagein a window's code so that the compiler takes the TX Text Control types. - The table. Tables.Add inserts a table with an ID that you choose, and GetItem returns it by that ID. Rows count from 1. IsHeader turns the first row into a header row that repeats on each page, CellFormat with BackColor shades it, and TableCell.Text fills the cells. The colors of TX Text Control are
System.Drawing.Colorvalues, not WPF brushes. After the table is inserted, the input position is below it. - The image. The Image constructor takes a file name and the index of the image format, 4 for PNG. Images.Add with the position -1 places the image at the input position, inline with the text.
- The header. HeadersAndFooters.Add creates the header, GetItem returns it, and the Selection of the HeaderFooter writes its text.
- Saving and showing. Save writes report.docx into the output folder, and a second call copies the document into a byte array in the TX Text Control format. TextControl.Load opens that byte array in the editor.
Run the Application
Press F5 and click Create Report. The editor shows the centered title, the paragraph, the table with its shaded header row, the line below it and the logo. report.docx in the output folder, bin\Debug\net8.0-windows for a .NET 8 project, contains the same document and opens in Microsoft Word.
The header "Sample Company Inc." is part of the document, but the editor shows headers and footers only when its ViewMode is PageView. Set the attribute ViewMode="PageView" on the TextControl element in XAML to see it.
Build the Document in the Editor Instead
The TextControl of the window has the same Selection, Tables, Images and HeadersAndFooters members, so the calls also work on the document the user sees:
textControl1.Selection.FontSize = 480;
textControl1.Selection.Text = "Quarterly Report\r\n";
textControl1.Tables.Add(4, 3, 10);
textControl1.HeadersAndFooters.Add(HeaderFooterType.Header);
Call such code after WPF has loaded the TextControl, for example in its Loaded event or in a button handler, not in the constructor of the window. Control Initialization explains why. A ServerTextControl remains the better choice for documents that are not meant for editing: it builds them without touching the document the user works on.
Next Steps
- Save as DOCX and PDF: save and convert documents in other formats.
- Print a Document: print the report with or without a dialog.
- Creating Documents: text, tables, images, sections and fields in code in detail.
- Create a Template: fill a template with data instead of building each document in code.