Rubrik: Drucker | VB-Versionen: VB.NET | 12.07.06 |
ListView-Inhalt drucken (VB 2005) Mit diesem Klassenmodul lässt sich ein ListView ausdrucken - entweder direkt auf den Drucker oder zunächst in eine Seitenvorschau. | ||
Autor: Matthias Zürn | Bewertung: | Views: 29.302 |
ohne Homepage | System: WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Mit unten aufgeführten Klassenmodul PrintListviewClass lässt sich der Inhalt eines ListView-Steuerelement auf dem Drucker ausgeben.
Schriftfarbe, Textausrichtung, GridLines, Hintergrundfarbe usw. werden direkt aus dem ListView übernommen.
Die Klasse PrintListView hat folgende Eigenschaften:
- HeaderColor: Ruft die Hintergrundfarbe des Headers ab oder legt diese fest.
- ColumnAutoSize: Legt fest, wie die Spaltenbreite bestimmt werden soll:
- None - Das Listview wird so gedruckt, wie es auch auf dem Bildschirm erscheint.
- ScretchColumn - Die Spaltenbreite wird, wie bei None, direkt vom Listview übernommen, allerdings werden Spalten, die einen breiteren Text aufweißen verlängert.
- AutosSize – Die Spaltenbreite wird nach breitesten Text einer Spalte bestimmt.
- Neu: Landscape: True, wenn der Ausdruck im Querformat erfolgen soll
Weiterhin verfügt die Klasse über folgende Methoden:
- Print: Druck das Listview aus.
- Preview: Zeigt einen PrintPreviewDialog
Das Klassenmodul "PrintListView
Erstellen Sie ein neues WindowsForms-Projekt und fügen dem Projekt ein neues leeres Klassenmodul mit folgendem Code hinzu:
Imports System.Drawing Imports System.Windows.Forms Public Class PrintListView Private LV As ListView Private SpaltenBreite As New List(Of Integer) Private TextHöhe As Integer Private OffsetSpalte As Integer Private OffsetZeile As Integer Private MerkerSpalte As Integer Private MerkerZeile As Integer Public HeaderColor As System.Drawing.Color = Color.LightGray Private WithEvents PD As New System.Drawing.Printing.PrintDocument Private PrintPrev As New System.Windows.Forms.PrintPreviewDialog Private asc As SizeColumn = SizeColumn.None Public Enum SizeColumn None ScretchColumn AutoSitze End Enum Public Property AutoSizeColumn() As SizeColumn Get Return asc End Get Set(ByVal value As SizeColumn) asc = value SizeColums() End Set End Property Public Property Landscape() As Boolean Get Return PD.DefaultPageSettings.Landscape End Get Set(ByVal value As Boolean) PD.DefaultPageSettings.Landscape = value SizeColums() End Set End Property Private Sub SizeColums() Dim breite As Integer Dim g As Graphics = LV.CreateGraphics Dim zähler As Integer SpaltenBreite.Clear() Select Case asc Case SizeColumn.None, SizeColumn.ScretchColumn For Each CH As Windows.Forms.ColumnHeader In LV.Columns SpaltenBreite.Add(CH.Width) Next Case SizeColumn.AutoSitze, SizeColumn.ScretchColumn If asc = SizeColumn.AutoSitze Then For Each CH As Windows.Forms.ColumnHeader In LV.Columns breite = g.MeasureString(CH.Text, LV.Font).Width + 20 SpaltenBreite.Add(breite) Next End If For Each LVI As ListViewItem In LV.Items zähler = 0 breite = g.MeasureString(LVI.Text, LV.Font).Width + 20 If asc = SizeColumn.AutoSitze Then SpaltenBreite.Add(breite) If SpaltenBreite(zähler) + 20 < breite Then SpaltenBreite(zähler) = breite For Each LVSI As ListViewItem.ListViewSubItem In LVI.SubItems breite = g.MeasureString(LVSI.Text, LV.Font).Width + 20 If SpaltenBreite(zähler) + 20 < breite Then SpaltenBreite(zähler) = breite zähler += 1 Next Next End Select End Sub Public Sub New() End Sub Public Sub New(ByVal ListViewToPrint As ListView) LV = ListViewToPrint Dim g As Graphics = LV.CreateGraphics TextHöhe = g.MeasureString("XyZ1!", LV.Font).Height + 5 SizeColums() SpaltenBreite.Add(0) g.Dispose() End Sub Public Sub Print() PD.Print() End Sub Public Sub Preview() PrintPrev.Document = PD PrintPrev.WindowState = FormWindowState.Maximized PrintPrev.ShowDialog() End Sub Private Sub PD_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PD.PrintPage e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias Dim left As Decimal = PD.DefaultPageSettings.Margins.Left Dim right As Decimal = PD.DefaultPageSettings.Margins.Right Dim top As Decimal = PD.DefaultPageSettings.Margins.Top Dim bottom As Decimal = PD.DefaultPageSettings.Margins.Bottom Dim PageWidth As Integer = PD.DefaultPageSettings.Bounds.Width - (right + left) Dim PageHeight As Decimal = PD.DefaultPageSettings.Bounds.Height - (top + bottom) Dim sf As New StringFormat sf.Alignment = StringAlignment.Near sf.LineAlignment = StringAlignment.Center Dim rf As New Rectangle Dim br As SolidBrush Dim br1 As SolidBrush Dim PosX As Integer = left Dim PosY As Integer = top Dim OffsetSpalte As Integer Dim OffsetZeile As Integer ' Header schreiben Do rf = New Rectangle(PosX, PosY, SpaltenBreite(OffsetSpalte + MerkerSpalte), TextHöhe) e.Graphics.FillRectangle(New SolidBrush(HeaderColor), rf) If LV.GridLines Then e.Graphics.DrawRectangle(Pens.Black, rf.X, rf.Y, rf.Width, rf.Height) e.Graphics.DrawString(LV.Columns(OffsetSpalte + MerkerSpalte).Text, LV.Font, Brushes.Black, rf, sf) PosX += SpaltenBreite(OffsetSpalte + MerkerSpalte) OffsetSpalte += 1 Loop Until PageWidth + left < PosX + SpaltenBreite(OffsetSpalte + MerkerSpalte) Or OffsetSpalte + MerkerSpalte > LV.Columns.Count - 1 PosX = left OffsetSpalte = 0 OffsetZeile = 0 Do OffsetZeile = 0 PosY = top + TextHöhe Do If (LV.Items(OffsetZeile + MerkerZeile).SubItems.Count > OffsetSpalte + MerkerSpalte) Then rf = New Rectangle(PosX, PosY, SpaltenBreite(OffsetSpalte + MerkerSpalte), TextHöhe) If LV.Items(OffsetZeile + MerkerZeile).UseItemStyleForSubItems = True Then br = New SolidBrush(LV.Items(OffsetZeile + MerkerZeile).BackColor) br1 = New SolidBrush(LV.Items(OffsetZeile + MerkerZeile).ForeColor) Else br = New SolidBrush(LV.Items(OffsetZeile + MerkerZeile).SubItems(OffsetSpalte + MerkerSpalte).BackColor) br1 = New SolidBrush(LV.Items(OffsetZeile + MerkerZeile).SubItems(OffsetSpalte + MerkerSpalte).ForeColor) End If e.Graphics.FillRectangle(br, rf) If LV.GridLines Then e.Graphics.DrawRectangle(New Pen(LV.ForeColor), rf) Select Case LV.Columns(OffsetSpalte + MerkerSpalte).TextAlign Case HorizontalAlignment.Center sf.Alignment = StringAlignment.Center Case HorizontalAlignment.Left sf.Alignment = StringAlignment.Near Case HorizontalAlignment.Right sf.Alignment = StringAlignment.Far End Select e.Graphics.DrawString(LV.Items(OffsetZeile + MerkerZeile).SubItems(OffsetSpalte + MerkerSpalte).Text, LV.Font, br1, rf, sf) End If PosY += TextHöhe OffsetZeile += 1 Loop Until PageHeight + top < PosY + TextHöhe Or OffsetZeile + MerkerZeile >= LV.Items.Count PosX += SpaltenBreite(OffsetSpalte + MerkerSpalte) OffsetSpalte += 1 Loop Until PageWidth + left < PosX + SpaltenBreite(OffsetSpalte + MerkerSpalte) Or OffsetSpalte + MerkerSpalte >= LV.Columns.Count If OffsetSpalte + MerkerSpalte = LV.Columns.Count And OffsetZeile + MerkerZeile = LV.Items.Count Then e.HasMorePages = False MerkerZeile = 0 MerkerSpalte = 0 OffsetSpalte = 0 OffsetZeile = 0 Exit Sub End If If OffsetZeile + MerkerZeile < LV.Items.Count Then MerkerZeile = OffsetZeile + MerkerZeile e.HasMorePages = True Exit Sub End If If MerkerSpalte = OffsetSpalte < LV.Columns.Count Then MerkerSpalte = OffsetSpalte + MerkerSpalte MerkerZeile = 0 e.HasMorePages = True Exit Sub End If End Sub End Class
Beispiel-Anwendung:
Für das kleine Demoprojekt benötigen Sie folgende Controls auf der Form1:
- Listview-Control (ListView1)
- 2 Buttons (Button1 für Preview und Button2 für Print)
Fügen Sie folgenden Code in den Codeteil der Form1 ein:
Public Class Form1 Private PrintListView As New ClassLibrary1.PrintListView Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Listview mit "Daten" füllen... ListView1.View = View.Details Dim x As Integer Dim y As Integer For x = 0 To 15 ListView1.Columns.Add("Spalte" & x.ToString) Next ListView1.Columns(5).TextAlign = HorizontalAlignment.Right ListView1.Columns(5).Width = 200 For y = 0 To 40 ListView1.Items.Add("Zeile" & y.ToString & " / Spalte1") If y Mod 2 = 0 Then ListView1.Items(y).BackColor = Color.LightGray For x = 1 To 15 ListView1.Items(y).SubItems.Add("Zeile" & y.ToString & " / Spalte" & x.ToString) Next Next ListView1.Items(3).ForeColor = Color.Blue ListView1.Items(7).UseItemStyleForSubItems = False ListView1.Items(7).SubItems(1).ForeColor = Color.Red ListView1.GridLines = True PrintListView = New ClassLibrary1.PrintListView(ListView1) PrintListView.AutoSizeColumn = PrintListView.SizeColumn.AutoSitze PrintListView.HeaderColor = Color.LightBlue End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ' Vorschau anzeigen.... und drucken... PrintListView.Preview() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click ' ohne Vorschau drucken PrintListView.Print() End Sub End Class