IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

4. diel - Tlač formuláre a ovládacích prvkov Windows Forms

V minulom diele sme dokončili programovanie formuláre a dnes ukážem akým štýlom vybrať ovládacie prvky umiestnené na formulári. V druhom diele sme vytvorili hlavičku funkcie:

private void PrintControls(System.Windows.Forms.Control ctrl, int x0, int y0){}

Túto funkciu doplníme kódom:

using System.Diagnostics;

//vytvoří setříděnou kolekci prvků a podle jejich skutečné polohy na formuláři
private void PrintControls(System.Windows.Forms.Control ctrl, int x0, int y0)
{
    int nbCtrl = ctrl.Controls.Count;
    int[] yPos = new int[nbCtrl];
    System.Windows.Forms.Control[] controls = new System.Windows.Forms.Control[nbCtrl];
    //načte prvky do kolekce
    for (int i = 0; i < nbCtrl; i++)
    {
        controls[i] = ctrl.Controls[i];
        yPos[i] = ctrl.Controls[i].Location.Y;
    }
    //setřídí prvky podle souřadnice Y
    System.Array.Sort(yPos, controls);
 //   Debug.Print("\r\n");      //Pro testy
    for (int i = 0; i < nbCtrl; i++)
    {
        // skutečná poloha prvků  jsou započítány okraje tištěného formuláře
        PrintControl(controls[i], x0 + controls[i].Location.X, y0 + controls[i].Location.Y);
 //       Debug.Print(i.ToString() + "     " + controls[i].Name.ToString());  //pro testy
    }
}

Pre testy doplníme záhlaví našej triedy System.Diagnostics a našu funkciu Debug.Print (.....) a budeme
sledovať výstup našej funkcie. Táto funkcia je volaná pomocou rekurzie, počet prechodov je daný rozložením a počtom užívateľských prvkov. Pre názornosť ukážky je použitá plná verzia programu.

Najlepšie vystihuje funkciu táto ukážka. Stojí za povšimnutie iba jeden priechod funkcií pre shapeContainer.

prvky formuláre - Okenné aplikácie v C # .NET vo Windows Forms výstup ladenia - Okenné aplikácie v C # .NET vo Windows Forms
// funkce rozdělí prvky na rodiče a jejich děti
// v případě dětí je provedena rekurze
private void PrintControl(Control ctrl, int locationX, int locationY)
{
    if (ctrl.Visible)
    {
        bool scanForChildControls = false;
        // Vytisknout ovládací prvky na formuláři
        PrintOneControl(ctrl, ParentControlPrinting.BeforeChilds, locationX, locationY,
            out scanForChildControls);
        // Vytisknout obsažené ovládací prvky (děti)
        if (scanForChildControls)
        {
            PrintControls(ctrl, locationX, locationY);  //Zde je volaná rekurze pro děti
            PrintOneControl(ctrl, ParentControlPrinting.AfterChilds, locationX, locationY,
            out scanForChildControls);
        }
    }
}

Ďalšie naše funkcie vylúči užívateľské prvky, ktoré nechceme tlačiť a generuje funkcie na tlač.

private void PrintOneControl(Control ctrl, ParentControlPrinting typePrint,
                int locationX, int locationY, out bool scanForChildControls)
    {
        scanForChildControls = true;
        string s = ctrl.GetType().ToString();
        bool founded = false;
        //vylučuji vybrané uživatelské prvky z tisku
        if (deletePrintControl.Any(sType => s.IndexOf("." + sType, StringComparison.Ordinal) >= 0))
        {
            founded = true;
            scanForChildControls = false;
        }
        //Process other type of control, beginning at the end of the list (use last add for a type)
        //Musíme začít -> prvý do kolekce -> prvý k tisku
        if (!founded)
            for (int i = delegatesforControls.Count - 1; i >= 0; i--)  // od konce na začátek
            {
                DelegateforControls d = (DelegateforControls)delegatesforControls[i];
                if (s.EndsWith(d.Typ))
                {
                    d.PrintFunction(ctrl, typePrint, locationX, locationY, out scanForChildControls);
                    //Debug.Print(d.Typ);
                    break;
                }
            }
    }

Tabuľka ukazuje ako generujeme funkcie pre tlač.

poradie tlače - Okenné aplikácie v C # .NET vo Windows Forms
Ak sa dobre pozeráte, niektoré funkcie sú
tú dvakrát a na našom formulári je tento prvok iba raz.

Pokiaľ má užívateľský prvok vlastnosť na seba viazať iné užívateľské prvky (napríklad GroupBox, UserControl, TabControl, PictureBox), ďalšie druhý priechod pre tlač je blokovaný pomocou testu (enum ParentControl­Printing) v kóde pre daný užívateľský prvok.

Príklad:

if (typePrint == ParentControlPrinting.BeforeChilds)
{
    MyClass2.PrintPictureBox(pb, x1, y1, width, height);
}

Posledná funkcia nám musí orezať presahujúcej časti ovládacieho prvku (dieťaťa) uloženého na rodičmi, napríklad GroupBox, Panel a podobne, na ktorých je uložený TextBox, ktorý presahuje cez rodičia.

//ořeže velikost těchto dětských prvků o část , které přesahují rodiče
private void TrimChild(Control ctrl, ref int x1, ref int y1 , out int width ,out int height )
 {
   width = ctrl.Width; height = ctrl.Height;
   if (ctrl.Parent == this.control)
   {
      RecRodic = new Rectangle(x1, y1, width, height);
      return;
   }
   else
   {
     Rectangle rec = new Rectangle(x1, y1, ctrl.Width, ctrl.Height);

     Rectangle rr = Rectangle.Intersect(rec, RecRodic);
     x1 = rr.Left;
     y1 = rr.Top;
     width = rr.Width;
     height = rr.Height;
   }
 }

Posledná funkcia našej triedy Class1 už volajú definované ovládacie prvky v konstruktoru Class1. Hlavičky týchto funkcií sme už vytvorili pri definovaní konstruktoru. Teraz je doplníme kódom. Tento je rovnaký pre ovládacie prvky, ktoré nemôžu byť kontajnerom pre ďalšie prvky. Ovládacie prvky, ktoré sú kontajnerom pre ďalšie prvky, majú v kóde pridané 2 riadky, dôvody som uviedol pri výklade poslednej tabuľky.

Funkcie PrinTextBox

#region "Tiskne TextBox"
private void PrintTextBox(Control ctrl,ParentControlPrinting typePrint, int x1, int y1,
                  out bool ScanForChildControls)
{
    //prvek nemůže mít kontejner to znamená nelze na něho uložit další ovládací prvek
        ScanForChildControls = false;
    int width = 0; int height = 0;
        TrimChild(ctrl, ref x1, ref y1, out width, out height);
        TextBox tb = (TextBox)ctrl;
    //Voláme funkci tisku pro TextBox
        MyClass2.FnPrintTextBox(tb, x1, y1, width, height);

}//PrintTextBox
 #endregion

Funkcie PrintShape

#region "Tiskne LineShape OvalShape RectangleShape"
private void PrintShape(Control ctrl,ParentControlPrinting typePrint,int x1, int y1,
                        out bool ScanForChildControls)
{
      ScanForChildControls = false;
      int width = 0; int height = 0;
      TrimChild(ctrl, ref x1, ref y1, out width, out height);
      Kreslivbshape pPack = new Kreslivbshape();
      pPack.PrintShape(graphics, ctrl, x1, y1 , RealPageSetting);
}
 #endregion

Ukážka funkcie pre UserControl

#region  "UserControl"
//jediná funkce public volá se externě z FormPrintDemo (není dodělána).
//fp.AddDelegateToPrintControlEx("PZ.Tisky.UserControl1", fp.PrintUserControl);
/*
public void PrintUserControl(Control ctrl,ParentControlPrinting typePrint,int x1, int y1,
                            out bool scanForChildControls)
{
     scanForChildControls = true; //má kontejner , může vázat další prvky
     int width = 0; int height = 0;
     TrimChild(ctrl, ref locationX, ref locationY, out width, out height);
     UserControl usc = (UserControl)ctrl;
     if (typePrint == ParentControlPrinting.BeforeChilds)
     {
         classTisk.FnPrintUserControl(usc, locationX, locationY, width, height);
     }
}
*/

Do Class1 nebudeme už písať žiadny ďalší kód. Musíme napísať hlavičky do dll triedy MyClass2 a skúsime vykonať kompiláciu.

Dopísanie kódu do MyClass2

//header soubor MyClass2.h a dopíšeme funkci
   public :
    void FnPrintTextBox(swf::TextBox^ tb,int x1, int y1 , int w1 , int h1);

//vytvoříme novou třídu v header soubor MyClass2.h a dopíšeme funkci
public ref class Kreslivbshape{
   public:
       void PrintShape(Graphics^ gr, Control ^control, int x, int y , Rectangle rec);

   private:
       Graphics^ graphics;
       int count;
       int x0;
       int y0;
};//Kresli prvky

//source soubor MyClass2.cpp
//tisk TextBox
void Class2::FnPrintTextBox(swf::TextBox^ tb,int x1, int y1 , int w1 , int h1)
{
};

//tisk LineShape OvalShape RectangleShape
void Kreslivbshape::PrintShape(Graphics^ gr, Control ^control, int x, int y , Rectangle rec )
{
};

Zostavíme riešenia (vykonáme kompilácii) v okne výstupu sa zobrazí:

Sestavení bylo úspěšně dokončeno.
========== Nové sestavení všeho: 3 úspěšně, 0 se nezdařilo, 0 přeskočeno ==========

V Ďalším diele iba doplníme nové funkcie v triede MyClass2 a sme hotoví. Pokračovanie nabudúce.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 96x (72.32 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Všetky články v sekcii
Okenné aplikácie v C # .NET vo Windows Forms
Článok pre vás napísal zpavlu
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
C# , C++ a assembler
Aktivity