Tak som sa rozhodol vytvorit maly priklad na ukazku ako si vytvorit svoj vlastny DocumentPaginator, cize objekt, ktory podla nejakych vstupnych dat vytvori postupnost stran na tlacenie, Tento priklad bude mozno poznat je urceny hlavne tym, ktory su na zaciatku a mozu tu najst odpoved ako tlacit viac stran.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using System.Globalization;
using System.Windows.Documents;
namespace FexikPrinting
{
public class PismenkovyDocumentPaginator : DocumentPaginator
{
string txt = string.Empty;
Typeface face = new Typeface(string.Empty);
Size sizePage;
Size sizeMax = new Size(0, 0);
/// <summary>
/// Vstupna premenna z tohto textu budem robit stranky na tlacenie
/// </summary>
public string Text
{
get { return txt; }
set { txt = value; }
}
public Typeface Typeface
{
get { return face; }
set { face = value; }
}
/// <summary>
/// Privatna funkcia na vytvorenie formatovaneho textu
/// </summary>
/// <param name="ch"></param>
/// <param name="face"></param>
/// <param name="em"></param>
/// <returns></returns>
FormattedText GetFormattedText(char ch, Typeface face, double em)
{
return new FormattedText(ch.ToString(), CultureInfo.CurrentCulture,
FlowDirection.LeftToRight, face, em, Brushes.Black);
}
/// <summary>
/// Vlastnos vzdy vrati true, ale nastavi maximalnu velkost pisma,
/// jednoducho porovna kazde pismenko , ktore chceme vytlacit
/// </summary>
public override bool IsPageCountValid
{
get
{
//urcim maximalnu velkost znaku na zaklade velkosti em
foreach (char ch in txt)
{
FormattedText formTxt = GetFormattedText(ch, face, 100);
sizeMax.Width = Math.Max(sizeMax.Width, formTxt.Width);
sizeMax.Height = Math.Max(sizeMax.Height, formTxt.Height);
}
return true;
}
}
/// <summary>
/// Pocet stran podla slabik textu
/// </summary>
public override int PageCount
{
get { return string.IsNullOrEmpty(txt) ? 0 : txt.Length; }
}
/// <summary>
/// Velkost stranky
/// </summary>
public override System.Windows.Size PageSize
{
get { return sizePage; }
set { sizePage = value; }
}
public override DocumentPage GetPage(int pageNumber)
{
DrawingVisual vis = new DrawingVisual();
DrawingContext dc = vis.RenderOpen();
//vypocitame velkost okrajov
double factor = Math.Min((PageSize.Width - 96) / sizeMax.Width,
(PageSize.Height - 96) / sizeMax.Height);
FormattedText formTxt = GetFormattedText(txt[pageNumber], face, factor * 100);
//vyhlada bod k zarovnaniu znaku na stred
Point ptText = new Point((PageSize.Width - formTxt.Width) / 2,
(PageSize.Height - formTxt.Height) / 2);
dc.DrawText(formTxt, ptText);
dc.Close();
//vytvorime z grafickeho objektu stranku
return new DocumentPage(vis);
}
public override IDocumentPaginatorSource Source
{
get { return null; }
}
}
}
Ako vidite logika tohto kodu je tak jednoducha, ze je az genialna :) Zobereme si to po poriadku objekt, ktory sme vytvorimi ma pridane dve smerodatne vlastnosti a to Text, to je obsah nasich stranok, je pouzite jednoduche rozmiestnenie jedneho znaku na stranku iba ako priklad, pre specialne zobrazenie by sme zvolili ine vstupne hodnoty, a este hodnota TypeFace, ktora udava typ, lepsie povedane vzor pisma.
Tak a teraz si ukazeme pouzitie:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Printing;
namespace FexikPrinting
{
class Program : Window
{
TextBox txtBox;
[STAThread]
public static void Main()
{
new Application().Run(new Program());
}
public Program()
{
Title = "Pismenkovy tisk";
SizeToContent = SizeToContent.WidthAndHeight;
StackPanel stack = new StackPanel();
Content = stack;
txtBox = new TextBox();
txtBox.Width = 250;
txtBox.Margin = new Thickness(12);
stack.Children.Add(txtBox);
Button btn = new Button();
btn.Content = "_Tisk...";
btn.Margin = new Thickness(12);
btn.Click += new RoutedEventHandler(btn_Click);
btn.HorizontalAlignment = HorizontalAlignment.Center;
stack.Children.Add(btn);
txtBox.Focus();
}
void btn_Click(object sender, RoutedEventArgs e)
{
PrintDialog dlg = new PrintDialog();
if (dlg.ShowDialog().GetValueOrDefault(false))
{
//skontrolujeme zi je nastavena orientacta na vysku
PrintTicket ticket = dlg.PrintTicket;
//ak nie nastavime ho ! je to len kvoli jednoduchosti prikladu
ticket.PageOrientation = PageOrientation.Portrait;
dlg.PrintTicket = ticket;
//vytvorime nas DocumentPaginator
PismenkovyDocumentPaginator paginator = new PismenkovyDocumentPaginator();
//nastavime mu text, z ktoreho on vytvori stranky
paginator.Text = txtBox.Text;
//nastavime velkost stranky
paginator.PageSize = new Size(dlg.PrintableAreaWidth, dlg.PrintableAreaHeight);
//zavla objekt print dokument
dlg.PrintDocument(paginator, "Nadpis: " + txtBox.Text);
}
}
}
}
Ako vidite staci vytvorit dialogovy objekt PrintDialog, kde vyberiete tlaciaren, osobne odporuca PDFCreator, lebo verim ze to nebudete tlacit:) V tomto dialogu mozete este nastavit zarovnanie stranky, a podal toho Vam vas DocumentPaginator vyreze stranky a posle ich tlacit.
Pripomienka do referencii si pridajte kniznicu ReachFramework, usetri Vam to cas ked budete skusat tento priklad, alebo si ho mozete stiahnut z prilohy.
Ak by bola poziadavka na nejake rozsirene riesenie alebo nieco specialne piste komentare, vsetka kritika je prijimana.
Prajem prijemny den ;)