none
DataGridView drucken RRS feed

  • Frage

  •  

    Hi,

     

    ich möchte gerne den Inhalt eines DataGridView drucken.

    Habe aber bis jetzt noch nix brauchbares im Netz gefunden.

    Die meisten Beispiele sin in C# oder VB .NET, ich arbeite aber mit C++/CLI.

    Kann mir da vielleicht einer weiter helfen, bin fast am verzweifeln.

    Habe schon gelesen, dass das drucken nicht mehr so einfach sein soll wie früher in VC++ 6.0 MFC.

    Habe aber mein Projekt nun unter der WindowsForms erstellt und möchte nicht alles wieder in die MFC stricken.

    Ich scheitere im Moment nur am drucken.

    Hat da jemand vielleicht ein Tipp für mich.

     

    Danke schon mal.

     

    Gruß, Doug_HH

    Samstag, 22. September 2007 23:30

Antworten

  • Das Beispiel druckt den Inhalt einer "RichTextBox" aus.
    Nun brauchen nur noch die Datensätze aus dem DataGridView in die RichTextBox transportiert werden.
    Das sollte aber nun nicht das Problem sein.
    Wollte dem Anwender eh noch die Möglichkeit lassen, den Text nachträglich zu bearbeiten.

    Um dieses Beispiel auszuprobieren, muss eine RichTextBox ein printDialog und ein printDocument sowie ein Button in Form1 vorhanden sein.

     

     

    Code Snippet

     

     

    //der Code vom Button

     

    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)

    {

    if (printDialog1->ShowDialog() ==::DialogResult::OK)

    {

    printDocument1->Print();

    }

     

    }

     

     

    //das PrintPage Ereignis von printDocument

     

    private: System::Void printDocument1_PrintPage(System::Object^ sender, System::Drawing::Printing::PrintPageEventArgs^ e)

    {

     

    SolidBrush^ drawBrush = gcnew SolidBrush(richTextBox1->ForeColor);

     

    //Create point for upper-left corner of drawing.

    PointF drawPoint = PointF(0.0,0.0);

     

    e->Graphics->DrawString(richTextBox1->Text,richTextBox1->Font,drawBrush,drawPoint);

    }

     

     

    Sonntag, 23. September 2007 18:08
  • Hier mal ein wenig Code, nur damit Du mal siehst, das dass doch etwas mehr an Code benötigt.

     

    Code Snippet

    try

    {

    float flZeilenProSeite = 0;

    float flImTextZeieln = 0;

    int flRandLinks = e->MarginBounds.Left -intSiteTop;

    int flRandOben = e->MarginBounds.Top -intSiteTop;

    //int flRandRechts = e->MarginBounds.Right;

    int flDruckbreite = Convert::ToInt32(e->MarginBounds.Width);

    int flVertikalPos = e->MarginBounds.Top -intSiteTop;

    int intDruckzeile = 0;

    String^ strZeile = nullptr;

    //errechnen der Zeilenanzahl pro Seite

    flZeilenProSeite = e->MarginBounds.Height / richTextBox1->Font->GetHeight(e->Graphics);

    flZeilenProSeite += 10;

    //Höhe einer Zeile

    int flZeilenHoehe = Convert::ToInt32(richTextBox1->Font->GetHeight(e->Graphics));

    while(intAktuelleZeile < intAnzahlZeilen)

    {

    strZeile = strAusgabezeilen[intAktuelleZeile];

    //Breite der ZEile berechnen

    SizeF sizeZeilenbreite = e->Graphics->MeasureString(strZeile,richTextBox1->Font);

    //Wenn eine Zeile breiter als der bedruckbare Bereich ist, dann wird hier die Höhe erweitert.

    int flZeilenHoeheAktuell = 0;

    if(sizeZeilenbreite.Width > flDruckbreite)

    {

    //Anzahl der Zeilen berechnen

    int intZeilenAnzahl = Convert::ToInt32(sizeZeilenbreite.Width) / flDruckbreite;

    //Rest berechnen; ist der Rest größer 0, wird eine Zeile "angehängt"

    int intZeilenRest = safe_cast<int>(sizeZeilenbreite.Width) % safe_cast<int>(flDruckbreite);

    if(intZeilenRest > 0)

    {

    intZeilenAnzahl++;

    }

    flZeilenHoeheAktuell = Convert::ToInt32(flZeilenHoehe) *intZeilenAnzahl;

    intDruckzeile = intDruckzeile + intZeilenAnzahl;

    }

    else

    {

    flZeilenHoeheAktuell = flZeilenHoehe;

    }

    //Zeichenbereich

    RectangleF^ rectBereich = gcnew RectangleF(Convert::ToSingle(flRandLinks), Convert::ToSingle(flVertikalPos), Convert::ToSingle(flDruckbreite), Convert::ToSingle(flZeilenHoeheAktuell));

    //Vertikale Position neu berechnen

    flVertikalPos = flVertikalPos + Convert::ToInt32(rectBereich->Height);

    //Ausdruck der aktuellen Zeile

    SolidBrush^ drawBrush = gcnew SolidBrush(richTextBox1->ForeColor);

    e->Graphics->DrawString(strZeile, richTextBox1->Font, drawBrush, Convert::ToSingle(flRandLinks),Convert::ToSingle(flVertikalPos));

    intAktuelleZeile++;

    intDruckzeile++;

    //Wenn noch Zeilen vorhanden sind, neue Seite erzeugen

    if(intDruckzeile >= flZeilenProSeite)

    {

    if(intAnzahlZeilen >= flZeilenProSeite)

    {

    e->HasMorePages = true;

    }

    else

    {

    e->HasMorePages = false;

    }

    //Verlassen der Routine wenn das Seitenende erreicht ist

    return;

    }

    }

    }

    catch(Exception^ e)

    {

    MessageBox::Show(e->Message,MessageTitel + " Fehler in " + e->Source ,MessageBoxButtons::OK,MessageBoxIcon::Exclamation);

    }

     

    Gruß, Doug_HH
    Freitag, 11. April 2008 20:58

Alle Antworten

  • Eigentlich sind C# oder VB.NET Beispiele sehr einfach nach C++/CLI zu "portieren"... man muss nur die Syntax anpassen... es ist halt Fleisarbeit...

    Sonntag, 23. September 2007 07:00
  • Das Beispiel druckt den Inhalt einer "RichTextBox" aus.
    Nun brauchen nur noch die Datensätze aus dem DataGridView in die RichTextBox transportiert werden.
    Das sollte aber nun nicht das Problem sein.
    Wollte dem Anwender eh noch die Möglichkeit lassen, den Text nachträglich zu bearbeiten.

    Um dieses Beispiel auszuprobieren, muss eine RichTextBox ein printDialog und ein printDocument sowie ein Button in Form1 vorhanden sein.

     

     

    Code Snippet

     

     

    //der Code vom Button

     

    private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)

    {

    if (printDialog1->ShowDialog() ==::DialogResult::OK)

    {

    printDocument1->Print();

    }

     

    }

     

     

    //das PrintPage Ereignis von printDocument

     

    private: System::Void printDocument1_PrintPage(System::Object^ sender, System::Drawing::Printing::PrintPageEventArgs^ e)

    {

     

    SolidBrush^ drawBrush = gcnew SolidBrush(richTextBox1->ForeColor);

     

    //Create point for upper-left corner of drawing.

    PointF drawPoint = PointF(0.0,0.0);

     

    e->Graphics->DrawString(richTextBox1->Text,richTextBox1->Font,drawBrush,drawPoint);

    }

     

     

    Sonntag, 23. September 2007 18:08
  • Ich bin es mal wieder.

    Ich habe es nun auch geschafft, den Inhalt von der richTextBox in einem printPreviewDialog1 anzuzeigen.

    Nun habe ich aber folgendes Problem.

    Der Text der richTextBox geht über die Größe vom printPreviewDialog1.

    Das heißt, der Text würde eigentlich zwei Seiten füllen, aber der printPreviewDialog1 zeigt nur eine Seite an, und der Rest wird abgeschnitten.

    Wie kann ich es einstellen, dass die tatsächliche Seitenzahl angezeigt wird?

    Kann mir da einer Helfen?

    Ich habe es durch den Befehl "HasMorePages = true;" versucht, nur das hat mir nicht wirklich geholfen, da er dann in einer Endlosschleife hängt und mir zahllose Seiten ausdrucken würde.

    Hat da jemand vielleicht eine Idee?

     

    Gruß Doug_HH

     

     

     

    Montag, 24. September 2007 19:57
  • Du mußt im Eigenschaftenfenster die rtfBox auf Multiline stellen und nue erstellen.

     

     

    mfg

    marcus.gonschior@t-online.de

     

    Mittwoch, 27. Februar 2008 20:23
  •  

    Hätte noch eine Idee, -

     

    habe mich viel mit dem dataGridView beschäftigt, da er viele Vorteile hat: ();

    aber um es kurz zu fassen: nicht zu schwer und nicht zu leicht zu bedienen.

     

    Also: Idee:

     

    man ließt die Zellen einzeln aus(das ist möglich, habe ich auch schon gemacht mit einer public int function in form1, die man aufruft).

     

    Man kann den Zellinhalt dann in eine rtfBox legen. Zwar sind da dann dort keine Umrahmungen der ZellValues, aber man kann sie ja untereinander listen oder mit Leerzeichen reihen.

     

    Aber wenn ich mich recht errinnere, war vorher auch die Rede von einer ListBox oder so etwas.

    wie das geht, weiß ich nicht, aber man kann das wehr wahrscheinlich übertragen, und diese ListBox wird wohl auch ein Raster haben.

     

    (der Code für diese Funktion steht im microsoft developer center unter ca. Thema beschrieben:

    ...   c++/datagridView/Zellen beschreiben, - bzw. Zellen auslesen).

     

    (die Sache mit der Seitenzahl würde dann eben entfallen, könnte man aber einfach das Programm veranlassen, immer nach 1 Abschnitt eben "S. ... \n" dazwischen zu texten. ..., also manuell vorzunehmen. Eine Rolleiste baut sich bei Zeilenüberschub in einer rtfbox automatisch ein. )

     

     

    gonschior

     

     

    Mittwoch, 19. März 2008 21:48
  • Es gibt im microsoft - Developer - Center eine Beispielfunktion <PopulateMyDatagridview>.

    Diese ließt nicht Werte ein, sondern füllt die Zellen mit String-Arrays.

     

    Diese arrays in eine rtfbox zu legen, und dann zu drucken, dürfte soweit() kein Problem sein.

     

    gonschior

     

    Samstag, 29. März 2008 22:32
  • Habe mich jetzt mit dem Print-Befehl auseinandergesetzt und ca. 6 gute Codebeispiele ausprobiert.

    Tatsächlich, es gibt ein Problem:

    Man kann sozus. so ziemlich alle <Drumherum-Einstellungen> vornehmen, wie:

    Seitenformat, Druckerauswahl, Prewiew, Print, und Close, - :

    alles klappt einwandfrei, nur:

    das Blatt bleibt leer.

    habe dann 2 weitere Codes ausprobiert, die einmal ein bekanntes Objekt als Value nehmen und einmal einen Dateipfad.

    Dabei ist mir aufgefallen, daß es quasi nicht möglich ist, dabei einen Bezug zu printDocument1 herzustellen, - selbst nicht über DocumentName(dieser wird bezuglos angenommen).

    So bleibt bisher nur 1 allgemeingültige Möglichkeit:

    erst in rtf-Box speichern und dann das rtf-File extern öffnen und dann normal über das Menue drucken.

    Möglicherweise kann das die normale Express-Edition garnicht.

    (Ausgangsfrage war von Doug_HH, hatte allerdings nicht erwartet, daß Print solche Probleme macht: in vb ist das kein Problem).

     

    gonschior

     

     

    Donnerstag, 10. April 2008 21:15
  • Hier mal ein wenig Code, nur damit Du mal siehst, das dass doch etwas mehr an Code benötigt.

     

    Code Snippet

    try

    {

    float flZeilenProSeite = 0;

    float flImTextZeieln = 0;

    int flRandLinks = e->MarginBounds.Left -intSiteTop;

    int flRandOben = e->MarginBounds.Top -intSiteTop;

    //int flRandRechts = e->MarginBounds.Right;

    int flDruckbreite = Convert::ToInt32(e->MarginBounds.Width);

    int flVertikalPos = e->MarginBounds.Top -intSiteTop;

    int intDruckzeile = 0;

    String^ strZeile = nullptr;

    //errechnen der Zeilenanzahl pro Seite

    flZeilenProSeite = e->MarginBounds.Height / richTextBox1->Font->GetHeight(e->Graphics);

    flZeilenProSeite += 10;

    //Höhe einer Zeile

    int flZeilenHoehe = Convert::ToInt32(richTextBox1->Font->GetHeight(e->Graphics));

    while(intAktuelleZeile < intAnzahlZeilen)

    {

    strZeile = strAusgabezeilen[intAktuelleZeile];

    //Breite der ZEile berechnen

    SizeF sizeZeilenbreite = e->Graphics->MeasureString(strZeile,richTextBox1->Font);

    //Wenn eine Zeile breiter als der bedruckbare Bereich ist, dann wird hier die Höhe erweitert.

    int flZeilenHoeheAktuell = 0;

    if(sizeZeilenbreite.Width > flDruckbreite)

    {

    //Anzahl der Zeilen berechnen

    int intZeilenAnzahl = Convert::ToInt32(sizeZeilenbreite.Width) / flDruckbreite;

    //Rest berechnen; ist der Rest größer 0, wird eine Zeile "angehängt"

    int intZeilenRest = safe_cast<int>(sizeZeilenbreite.Width) % safe_cast<int>(flDruckbreite);

    if(intZeilenRest > 0)

    {

    intZeilenAnzahl++;

    }

    flZeilenHoeheAktuell = Convert::ToInt32(flZeilenHoehe) *intZeilenAnzahl;

    intDruckzeile = intDruckzeile + intZeilenAnzahl;

    }

    else

    {

    flZeilenHoeheAktuell = flZeilenHoehe;

    }

    //Zeichenbereich

    RectangleF^ rectBereich = gcnew RectangleF(Convert::ToSingle(flRandLinks), Convert::ToSingle(flVertikalPos), Convert::ToSingle(flDruckbreite), Convert::ToSingle(flZeilenHoeheAktuell));

    //Vertikale Position neu berechnen

    flVertikalPos = flVertikalPos + Convert::ToInt32(rectBereich->Height);

    //Ausdruck der aktuellen Zeile

    SolidBrush^ drawBrush = gcnew SolidBrush(richTextBox1->ForeColor);

    e->Graphics->DrawString(strZeile, richTextBox1->Font, drawBrush, Convert::ToSingle(flRandLinks),Convert::ToSingle(flVertikalPos));

    intAktuelleZeile++;

    intDruckzeile++;

    //Wenn noch Zeilen vorhanden sind, neue Seite erzeugen

    if(intDruckzeile >= flZeilenProSeite)

    {

    if(intAnzahlZeilen >= flZeilenProSeite)

    {

    e->HasMorePages = true;

    }

    else

    {

    e->HasMorePages = false;

    }

    //Verlassen der Routine wenn das Seitenende erreicht ist

    return;

    }

    }

    }

    catch(Exception^ e)

    {

    MessageBox::Show(e->Message,MessageTitel + " Fehler in " + e->Source ,MessageBoxButtons::OK,MessageBoxIcon::Exclamation);

    }

     

    Gruß, Doug_HH
    Freitag, 11. April 2008 20:58
  • Deine zusätzl. Einstellungen sind sehr gut, richtig und hätte ich auch garnicht gewußt, - vielen Dank dafür.

    Meinte allerdings etwas recht Einfaches: Ich kann meinem printDocument keinen Text zuweisen, es bleibt inhaltlos.

    Selbst wenn ich den documentName mit existierenden Dateien gleichsetze oder sogar directoryEntry benutze mit Pfad, wird nur eine leere Seite gedruckt.

    Aber dann noch zur Frage mit dem dataGrid: habe unter dieser Nachricht einen thread: dataGridView gemeintes Beisp. oder so:

    Wenn man alle sonst. Funktionen auskommentiert bis auf die Textzuweisung und die Zuordnung zu den rows, läuft es einwandfrei und nun kann man die Stringwerte doch auch in eine rtfBox legen, danach kann man drucken(was Du ja wohl kannst.)

     

    gonschior

     

    Samstag, 12. April 2008 06:04
  • Hallo Doug_HH, -

     

    mein Problem hat sich gelößt:

     

    Es war ein einfacher Fehler(d.h.: das wußte ich nur nicht):

    Bei dem Code lag eine veraltete Schreibweise vor: man mußte nur in der Parameterliste des DruckVoids die Sternchen(*) gegen den modernen Deckel(^) auswechseln.

     

    Jetzt geht es soweit, wie ich das will.

    Die Feineinstellungen nehme ich später vor.

     

    Danke

    gonschior

     

    Samstag, 12. April 2008 10:25