[C#] Printen uitlijnen.

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • tha_crazy
  • Registratie: Maart 2007
  • Laatst online: 22:16
Hey iedereen.
Ik heb even een snel vraagje, ik zit met een probleem.
Na veel pijn en moeite heb ik voor elkaar weten te krijgen dat je kan printen vanuit 3 listboxen en dit netjes onder elkaar wordt gezet. natuurlijk met wat hulp van wat scripts op internet.
Nu zit ik echter met een probleem.
De tekst die geprint wordt wordt niet goed uitgelijnt.
het ziet er ongeveer als volgt uit:
code:
1
2
3
Hardware - Number - Serial
iets1 - nummertje - seriecode
iets2 - nummer2 - ennogeenseriecode


wat ik echter wil hebben is het volgende:
code:
1
2
Hardware               Number               Serial
Iets1                  Nummertje            Seriecode

Dat het iets meer duidelijk is.

ik gebruik de volgende code om dit uit te voeren:
code:
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
    public class TextDocument : PrintDocument
    {
        private string[] text;
        private int pageNumber;
        private int offset = 0;

        public string[] Text
        {
            get { return text; }
            set { text = value; }
        }

        public int PageNumber
        {
            get { return pageNumber; }
            set { pageNumber = value; }
        }

        public int Offset
        {
            get { return offset; }
            set { offset = value; }
        }

        public TextDocument(string[] text)
        {
            this.Text = text;
        }
    }

een class voor het opbouwen van de pagina, de paginanummering voor als er meer dan 1 is, en natuurlijk de tekst ect.

code:
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
        private void button4_Click(object sender, EventArgs e)
        {
            
            int items = listBox1.Items.Count + 1;
            string[] printText = new string[items];
            printText[0] = "Hardware  -  Number  -  Serial";
            for (int i = 1; i != items; i++)
            {
                int num = i - 1;
                //printText[i] = i.ToString();
                printText[i] = listBox2.Items[num].ToString() + " - " + listBox1.Items[num].ToString() + " - " + listBox3.Items[num].ToString();
            }

            PrintDocument doc = new TextDocument(printText);
            doc.PrintPage += this.Doc_PrintPage;

            PrintDialog dlgSettings = new PrintDialog();
            dlgSettings.Document = doc;

            if (dlgSettings.ShowDialog() == DialogResult.OK)
            {
                doc.Print();
            }

        }

Het opbouwen van het printdocument en een dialoog laten zien om een printer te selecteren.

code:
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
          using (Font font = new Font("Arial", 10))
          {
            float lineHeight = font.GetHeight(e.Graphics);

            float x = e.MarginBounds.Left;
            float y = e.MarginBounds.Top;
     
            doc.PageNumber += 1;
     
            while ((y + lineHeight) < e.MarginBounds.Bottom &&
              doc.Offset <= doc.Text.GetUpperBound(0))
            {
              e.Graphics.DrawString(doc.Text[doc.Offset], font,
                Brushes.Black, x, y);
     
              doc.Offset += 1;
     
              y += lineHeight;
            }
     
            if (doc.Offset < doc.Text.GetUpperBound(0))
            {
              e.HasMorePages = true;
            }
            else
            {
              doc.Offset = 0;
            }
          }

Het echt opbouwen van de pagina, de tekst in de juiste font plaatsen en het printen deels verzorgen.

Nu vroeg ik mij af of iemand hier een idee voor heeft.
Het geven van meedere spaties in de opbouw (2e code stuk) zal geen nut hebben gezien die hem dan gewoon wat verder plaatst als het aantal karakters meer of minder is.

Nu zat ik er ook nog aan te denken om het aantal karakters te tellen en hiermee de lengte bepalen die er tussen moet zitten, dit is niet de makkelijkste oplossing maar wel mogelijk lijkt mij.

Heeft iemand misschien nog een simpele manier om dit uit te voeren ?

Groet,
vincent

Acties:
  • 0 Henk 'm!

  • Flard
  • Registratie: Februari 2001
  • Laatst online: 26-09 22:22
Als je nu op regel 13 de tekst die je wilt gaan printen opdeelt (string.Split()) in de kolommen die je wilt afdrukken, en vervolgens ieder van de kolommen afdrukt op de gewenste x (de y is overal gelijk).

Daarbij moet je dan daarboven ergens de x-posities bepalen, want die moet natuurlijk voor alle regels gelijk zijn.

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 19-09 10:19
Hoewel Flard's optie duidelijk de beste is voor precieze controlle gaat het wel fout als een artikel te lang is.

Je zou gewoon "een tekst \t \t lalal" kunnen doen om 2 tabs in te voegen, iets minder controlle maar als iets echt te lang is verschuift gewoon de hele rij een stukje op en gaat het niet over elkaar heen (of je zou een check voor lengte moeten maken en teksten daarna afkorten, er is dacht ik een functie die de tekst lengte meet meegenomen de echte tekst en het lettertype (dus die houder er rekening mee dat o breder is dan r in veel lettertypen)

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • Flard
  • Registratie: Februari 2001
  • Laatst online: 26-09 22:22
Hangt dan een beetje af van je definitie van fout... In het ene geval gaat er tekst over elkaar heen, in het andere geval lopen de kolommen out of sync. In het beide gevallen loop je het risico dat de tekst rechts van 'het papier af' loopt.

Maar inderdaad, met Graphics.MeasureString kun je meten hoe groot de te tekenen string is. Op die manier kun je inderdaad ook kijken of de tekst in een rectangle past. Volgens mij kun je met de TextRenderer class zelfs tekst tekenen en automatisch puntjes tonen als de tekst te breed is. Volgens mij kan TextRenderer ook automatisch word-wrappen (automatische regeleindes) (Misschien Graphics.DrawString ook wel in een overload).

Acties:
  • 0 Henk 'm!

  • tha_crazy
  • Registratie: Maart 2007
  • Laatst online: 22:16
Flard, jou oplossing was inderdaad de beste.
Ik ben er al veel mee opgeschoten.
heb het nu als volgt:

code:
1
2
float x = 50;
float y = 50;

De afstanden

code:
1
2
3
                    e.Graphics.DrawString(doc.Text_left[doc.Offset], font, Brushes.Black, x, y);
                    e.Graphics.DrawString(doc.Text_center[doc.Offset], font, Brushes.Black, x + 200, y);
                    e.Graphics.DrawString(doc.Text_right[doc.Offset], font, Brushes.Black, x + 400, y);

het tekenen van de text op de juiste plaats.
zoals je ziet heb ik nu van 1 text 3 texten gemaakt.
Zo kan ik nu oko gemakkelijker kopjes plaatsen.
Hardstikke bedankt !

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Heb je er eens over nagedacht om eens XPS te proberen? In the System.Windows.Document namespace is gewoon een table beschikbaar. XPS kan content eventueel zelfs over meerdere pagina's uitsmeren en ook wrapping is geen enkel probleem.

De manier waarop je een XPS document opbouwt is erg vergelijkbaar bij xhtml. Wij gebruiken een niet zichtbaar FlowDocumentReader waarom de Print methode wordt aangeroepen.

Hoewel ik hier spreek over een XPS document moet ik wel bekennen dat wij het genereren beperken tot FlowDocument instances. Een XPS bestaat uit een zip archief met daarin 1 of meerdere flow documents en eventuele resources.

If it isn't broken, fix it until it is..

Pagina: 1