2. diel - Tlač formuláre a ovládacích prvkov Windows Forms
Vitajte u druhého dielu, ktorý vás uvedie do problematiky tlače formulára a ovládacích prvkov. V dnešnej lekcii budeme pokračovať písaním kódu v knižnici dll (MyClass1). V prvom diele sme definovali konštruktor takto:
public Class1(System.Windows.Forms.Control ctrl){}
Doplníme konštruktor novým kódom:
public Class1(System.Windows.Forms.Control ctrl) { this.control = ctrl; //tato kolekce slouží k vyloučení prvků z tisku deletePrintControl = new List<string>(); delegatesforControls = new List<DelegateforControls>(); //naplní kolekci prvky , které mohu tisknout AddDelegateToPrintControl("Microsoft.VisualBasic.PowerPacks.ShapeContainer", PrintShape); AddDelegateToPrintControl("System.Windows.Forms.TextBox", PrintTextBox); //další prvky které chci tisknout nutno doplnit programem na příklad: //AddDelegateToPrintControl("System.Windows.Forms.LinkLabel", PrintLinkLabel); //AddDelegateToPrintControl("System.Windows.Forms.ComboBox", PrintComboBox); //AddDelegateToPrintControl("System.Windows.Forms.CheckBox", PrintCheckBox); //AddDelegateToPrintControl("System.Windows.Forms.RadioButton", PrintRadioButton); //AddDelegateToPrintControl("System.Windows.Forms.DateTimePicker", PrintDateTimePicker); //AddDelegateToPrintControl("System.Windows.Forms.NumericUpDown", PrintNumericUpDown); //další možné ovládací prvky k tisku }
Ak sa pokúsime vykonať príkaz VS -> Zostavenie -> Zostaviť riešenie, získame nasledujúci výstup:
Sestavení: 1 úspěšně, 1 se nezdařilo, 1 aktuální, 0 přeskočeno Seznam chyb: Název PrintTextBox v aktuálním kontextu neexistuje. Název PrintShape v aktuálním kontextu neexistuje.
Toto chybové hlásenie je spôsobené volaním funkcií, ktoré nie sú zadané. Zatiaľ vytvoríme hlavičky požadovaných funkciu takto:
//Funkce , budou provádět tisk #region "Tiskne TextBox" private void PrintTextBox(Control ctrl,ParentControlPrinting typePrint,int locationX, int locationY, out bool ScanForChildControls) { ScanForChildControls = false; }//PrintTextBox #endregion #region "Tiskne LineShape , OvalShape a RectangleShape" private void PrintShape(Control ctrl,ParentControlPrinting typePrint,int locationX, int locationY, out bool ScanForChildControls) { ScanForChildControls = false; }//print Shape #endregion
Ak sa pokúsime znova vykonať príkaz VS -> Zostavenie -> Zostaviť riešenie, bude výstup už nasledujúci:
Sestavení: 2 úspěšně, 0 se nezdařilo, 1 aktuální, 0 přeskočeno
Úprava funkcie MyPrint ()
V minulom dieli sme vytvorili hlavičku funkcie, ktorá je spúšťací funkcií pre tlač. Vylepšiť túto funkciu môžeme pomocou PrintPreviewDialog, ktorá je súčasťou VS.
private bool landscape = true ; private bool printPreview = true; private Rectangle RealPageSetting = new Rectangle(100, 100, 960, 600); //Velikost k tisku private Rectangle PageSettingA4 = new Rectangle(0,0, 1169, 827); // Velikost A4 v pixelech // Spuštění tisku. Výpočet výchozí polohy a orientace // Definuje objekt odešle výstup do tiskárny při tisku z aplikace model Windows Forms public void MyPrint() { using (PrintDocument pd = new PrintDocument()) { pd.DefaultPageSettings.Landscape = landscape; //Událost volána v případě potřeby výstup vytisknout aktuální stránku pd.PrintPage += PdPrintPage; //text v hlavičce formuláře pd.DocumentName = control.Text; if (printPreview) { //Představuje dialogové okno pole formuláře, který obsahuje PrintPreviewControl k tisku z aplikace model Windows Forms. using (var pp = new PrintPreviewDialog()) { if (landscape) pp.ClientSize = new Size(580, 410); else pp.ClientSize = new Size(410, 580); pp.Document = pd; pp.WindowState = FormWindowState.Normal; pp.ShowDialog(); } } else { pd.Print(); //Spustí proces tisku dokumentu. } } }
Udalosť PdPrintPage nám začne tlačiť formuláre a
ovládacích prvkov. Najprv musíme pripraviť na tlač
Form1 z našej (exe) aplikácie a to bez ovládacích prvkov.
Vykonáme pridanie referencií ako v minulom dieli tentoraz z triedy Class1 na
Class2. Prieskumník riešenia -> projekt MyClass1 -> pravé tlačidlo
myši -> pridať odkaz -> solution -> MyClass2. Ďalej Prieskumník
riešenia -> projekt MyClass1 -> pravé tlačidlo myši -> pridať
odkaz -> Framework -> Micr.Visual.Basic.
V generované udalosti PdPrintPage nebudeme spúšťať funkcie odkazujúce na FormPrintDemo.Class2. Tieto funkcie sprístupníme neskôr, sú využívané aj ovládacími prvkami.
Jedná sa o funkcie:
FormPrintDemo.Class2.FnSetGraphics(graphics);
FormPrintDemo.Class2.FnRealPageSettingsBounds(RealPageSetting); // Reálná velikost stránky k tisku
FormPrintDemo.Class2.FnDrawBachgRoundImage(control.BackgroundImage, control.BackgroundImageLayout, RealPageSetting);
Výsledná funkcia bude vyzerať:
private void PdPrintPage(object sender, PrintPageEventArgs ev) { graphics = ev.Graphics; // FormPrintDemo.Class2.FnSetGraphics(graphics); //reálná velikost stránky k tisku // FormPrintDemo.Class2.FnRealPageSettingsBounds(RealPageSetting); graphics.Clip = new Region(PageSettingA4); //barva formuláře Form using (SolidBrush brush = new SolidBrush(control.BackColor)) graphics.FillRectangle(brush, RealPageSetting); //Image pozadí formuláře //FormPrintDemo.Class2.FnDrawBachgRoundImage(control.BackgroundImage, control.BackgroundImageLayout, RealPageSetting); //vykreslí platné ohraničení stránky pro návrh if (Ohraniceni) { using (Pen pen = new Pen(Color.Red)) graphics.DrawRectangle(pen, RealPageSetting); Rectangle rec = Rectangle.Inflate(PageSettingA4, -2, -2); using (Pen pena = new Pen(Color.Black)) graphics.DrawRectangle(pena, rec); } graphics.ResetClip(); //tisk nadpisu formuláře , velikost písma , podtržení písma if (!String.IsNullOrEmpty(control.Text)) { using (StringFormat sf = new StringFormat()) { sf.LineAlignment = StringAlignment.Near; sf.Alignment = StringAlignment.Center; using (SolidBrush brush = new SolidBrush(Color.Black)) graphics.DrawString(control.Text, control.Font, brush, RealPageSetting, sf); } } PrintControls(control, RealPageSetting.X, RealPageSetting.Y ) ; //Nebudou vytištěny další stránky ev.HasMorePages = false; }
Volaná funkcia PrintControls (control, RealPageSetting.X, RealPageSetting.Y); bude pripravovať na tlač ovládacie prvky a bude volané rekurziu. Vytvoríme hlavičku tejto funkcie a vykonáme zostavenie našich projektov.
private void PrintControls(System.Windows.Forms.Control ctrl, int x0, int y0){}
V okne Výstup:
Sestavení bylo úspěšně dokončeno. Sestavení: 2 úspěšně, 0 se nezdařilo, 1 aktuální, 0 přeskočeno.
Malé odbočenie
Každý ovládací prvok je trieda. Na formulár môžeme ovládací prvok pretiahnuť pomocou VS -> panel s nástrojmi alebo programovo.
//programově using System.Collections.Generic; public partial class Form1 : Form { private static TextBox tb = new TextBox(); //vytvoří text box private List<TextBox> tbp = new List<TextBox>(3){tb,tb,tb};//nebo pole TextBoxu }
Rozdiel je vo vytváraní prvkov z doplnkov balíka Visual Basic.
using Microsoft.VisualBasic.PowerPacks; using mvb = Microsoft.VisualBasic.PowerPacks; public partial class Form1 : Form { private mvb.ShapeContainer mShape = new mvb.ShapeContainer(); private mvb.LineShape line1 = new mvb.LineShape(); private mvb.LineShape line2 = new mvb.LineShape(); private mvb.OvalShape oval1 = new OvalShape(); //konstruktor shapeContainer.Parent = this; line1.Parent = shapeContainer; line2.Parent = shapeContainer; oval1.Parent = shapeContainer; }
Z týchto dôvodov je dekódovanie tlače rozdielne.
Trochu teórie a použitých názvov
Ak sa pozrieme na hotovú konštrukciu triedy Class1, jedná sa o návrhový
vzor továrne na objekty.
Čo sú návrhové vzory?
Návrhový vzor je spôsob postupu, podľa ktorého upravíme náš postup pri
tvorbe programu.
Výhody továrenské metódy:
- Skrýva zložitosť tvorby od spotrebiteľa.
- Zabezpečuje, že logika vytvorenie objektu bude na jednom mieste.
- Pomáha prispôsobiť tvorbu, bez toho aby ste rušili logiku spotrebiteľa.
- Prináša logické oddelenie tvorby a použitia.
Rekurzia
Rekurziu používame keď nejaká metóda volá sama seba. Uvediem jednoduchý príklad výpočtu faktoriálu.
private long Faktorial(int x) { if(x==0) return 1; else return x*Faktorial(x-1); }
Názvy
- Kontajner v našom prípade kolekcie, do ktorej budeme vkladať ovládacie prvky.
- Rodič je náš formulár, dieťa ovládací prvok nakreslený na našom formulári.
- Ak ovládací prvok je kontajnerom pre ďalšie ovládacie prvky, potom formulár je starý rodič, na ňom nakreslený ovládací prvok je rodič a najvyššie položený nakreslený prvok je dieťa.
Pokračovanie v budúcom diele.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 96x (634.66 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#