Results 1 to 7 of 7

Thread: [RESOLVED] Printdocument doesn't print icon

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    71

    Resolved [RESOLVED] Printdocument doesn't print icon

    I am trying to use Printdocument to print the content of my Listview1. The first column is an image 16x16. The code recognize the .ImageIndex but the "Icon" column (first column) stays empty.

    Code:
    Private Sub PrintDetails(ByRef e As System.Drawing.Printing.PrintPageEventArgs)
            If ListView1.Visible = True Then
                Static LastIndex As Integer = 0
                Static CurrentPage As Integer = 0
                'Getting the current dpi so the textleftpad
                'will be the same on a different dpi than
                'the 96 i'm using. Won't make much of a difference though.
                Dim DpiGraphics As Graphics = Me.CreateGraphics
                Dim DpiX As Integer = DpiGraphics.DpiX
                Dim DpiY As Integer = DpiGraphics.DpiY
                DpiGraphics.Dispose()
                Dim X, Y As Integer
                Dim ImageWidth As Integer
                Dim TextRect As Rectangle = Rectangle.Empty
                Dim TextLeftPad As Single = CSng(4 * (DpiX / 96)) '4 pixel pad on the left.
                Dim ColumnHeaderHeight As Single = CSng(ListView1.Font.Height + (10 * (DpiX / 96))) '5 pixel pad on the top an bottom
                Dim StringFormat As New StringFormat
                Dim PageNumberWidth As Single = e.Graphics.MeasureString(CStr(CurrentPage), ListView1.Font).Width
                'Specify the text should be drawn in the center of the line and
                'that the text should not be wrapped and the text should show
                'ellipsis would cut off.
                StringFormat.FormatFlags = StringFormatFlags.NoWrap
                StringFormat.Trimming = StringTrimming.EllipsisCharacter
                StringFormat.LineAlignment = StringAlignment.Center
                CurrentPage += 1
                'Start the x and y at the top left margin.
                X = CInt(e.MarginBounds.X)
                Y = CInt(e.MarginBounds.Y)
                'Draw the column headers
                For ColumnIndex As Integer = 0 To ListView1.Columns.Count - 1
                    TextRect.X = X
                    TextRect.Y = Y
                    TextRect.Width = ListView1.Columns(ColumnIndex).Width
                    TextRect.Height = ColumnHeaderHeight
                    e.Graphics.FillRectangle(Brushes.LightGray, TextRect)
                    e.Graphics.DrawRectangle(Pens.DarkGray, TextRect)
                    'TextLeftPad adds a little padding from the gridline. Add it to the left and subtract it from the right.
                    TextRect.X += TextLeftPad
                    TextRect.Width -= TextLeftPad
                    e.Graphics.DrawString(ListView1.Columns(ColumnIndex).Text, ListView1.Font, Brushes.Black, TextRect, StringFormat)
                    'Move the x position over the width of the column width. Since I subtracted some padding add the padding back when offsetting.
                    X += TextRect.Width + TextLeftPad
                Next
                'Just drew the headers. Move the Y down the height of the column headers.
                Y += ColumnHeaderHeight
                'Now draw the items. If this is the first page then the last index will be zero. If its not then the last index
                'will be the last index we tried to draw but had no room.
                For i = LastIndex To ListView1.Items.Count - 1
    
                    With ListView1.Items(i)
                        'Start the x at the pages left margin.
                        X = CInt(e.MarginBounds.X)
                        'Check for Last Line
                        If Y + .Bounds.Height > e.MarginBounds.Bottom Then
                            'This item won't fit. subtract 1 from i so the next time this sub is entered we can start with this item.
                            LastIndex = i - 1
                            e.HasMorePages = True
                            StringFormat.Dispose()
                            'Draw the current page number before leaving.
    
                            e.Graphics.DrawString(CStr(CurrentPage), ListView1.Font, Brushes.Black, (e.PageBounds.Width - PageNumberWidth) / 2, e.PageBounds.Bottom - ListView1.Font.Height * 2)
                            Exit Sub
                        End If
                        'Print Images.
                        'The image width is used so we can draw the gridline
                        'around the image about to be drawn. You'll see it
                        'below.
                        ImageWidth = 0
                        If ListView1.SmallImageList IsNot Nothing Then
                            'If the image key is set then draw the image with the key . If not draw the image with the index. A tiny bit of validation would be good.
                            If Not String.IsNullOrEmpty(.ImageKey) Then
                                e.Graphics.DrawImage(ListView1.SmallImageList.Images(.ImageKey), X, Y)
                            ElseIf .ImageIndex >= 0 Then
                                e.Graphics.DrawImage(ListView1.SmallImageList.Images(.ImageIndex), X, Y)
                            End If
                            ImageWidth = ListView1.SmallImageList.ImageSize.Width
                        End If
                        'Now draw the subitems. using the columns count so the grid lines can be drawn. If used the subitems count then the table would not be full if some subitems where less
                        'than others.
                        For ColumnIndex As Integer = 0 To ListView1.Columns.Count - 1
                            TextRect.X = X
                            TextRect.Y = Y
                            TextRect.Width = ListView1.Columns(ColumnIndex).Width
                            TextRect.Height = .Bounds.Height
                            Dim bColor As Integer = ListView1.Items(i).BackColor.ToArgb
                            Dim myBColor As Color = ColorTranslator.FromHtml(bColor)
                            e.Graphics.FillRectangle(New SolidBrush(myBColor), TextRect)
                            If ListView1.GridLines Then
                                e.Graphics.DrawRectangle(Pens.DarkGray, TextRect)
                            End If
                            'If an image is drawn then shift over the x to
                            'accomadate its width. If this was shifted before
                            'now then the gridline with draw rect above would be
                            ' on the wrong side of the image.
                            If ColumnIndex = 0 Then TextRect.X += ImageWidth
                            'Add a little padding from the gridline.
                            TextRect.X += TextLeftPad
                            TextRect.Width -= TextLeftPad
                            If ColumnIndex < .SubItems.Count Then
                                'This item has at least the same number of
                                'subitems as the current column index.
                                Dim TColor As Integer = ListView1.Items(i).SubItems(ColumnIndex).ForeColor.ToArgb
                                Dim myTColor As Color = ColorTranslator.FromHtml(TColor)
                                e.Graphics.DrawString(.SubItems(ColumnIndex).Text, ListView1.Font, New SolidBrush(myTColor), TextRect, StringFormat)
                            End If
                            'Shift the x of the width of this subitem.
                            'Add some padding to the left side of the text
                            'so need to add it back.
                            X += TextRect.Width + TextLeftPad
                        Next
                        'Set the next line
                        Y += .Bounds.Height
                    End With
    
                Next
                'Draw the final page number.
                e.Graphics.DrawString(CStr(CurrentPage), ListView1.Font, Brushes.Black, (e.PageBounds.Width - PageNumberWidth) / 2, e.PageBounds.Bottom - ListView1.Font.Height * 2)
                StringFormat.Dispose()
                LastIndex = 0
                CurrentPage = 0
            End If
    
        End Sub

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,347

    Re: Printdocument doesn't print icon

    There's no way that all that code is relevant to the problem. You should already have done this for yourself but you definitely should be doing it for us: create a simple test project and include ONLY the functionality that is relevant to this problem. Once you isolate the functionality, you may well see the cause for yourself because, like us, you won't have to wade through reams of irrelevant code to get to the important part. If you still can't figure it out, at least you'll be helping us to help you.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    71

    Re: Printdocument doesn't print icon

    thank you for your reply. I understand what you say however the next guy will tell me that he needs the whole code to be able to help me.
    I believe the next line should draw the image, but it doesn't
    Code:
    e.Graphics.DrawImage(ListView1.SmallImageList.Images(.ImageIndex), X, Y)
    Last edited by clausowitz; Apr 15th, 2021 at 10:58 AM.

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    71

    Re: Printdocument doesn't print icon

    After a lot of testing I found out where the code doesn't do what it should.

    An updated version of the code using colors doesn't work.
    Code:
                 Dim bColor As Integer = ListView1.Items(i).BackColor.ToArgb
                            Dim myBColor As Color = ColorTranslator.FromHtml(bColor)
                            e.Graphics.FillRectangle(New SolidBrush(myBColor), TextRect)
    
                            Dim TColor As Integer = ListView1.Items(i).SubItems(ColumnIndex).ForeColor.ToArgb
                            Dim myTColor As Color = ColorTranslator.FromHtml(TColor)
                            e.Graphics.DrawString(.SubItems(ColumnIndex).Text, ListView1.Font, New SolidBrush(myTColor), TextRect, StringFormat)
    Not yet know why

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,347

    Re: Printdocument doesn't print icon

    This is an example of why you need to isolate specific functionality. If you can't fill a rectangle or draw a string then obviously the issue has nothing to do with images. Take it back to basics. The most likely explanation seems to be that you're drawing in the wrong place but there's so much code there it's hard to know.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Apr 2021
    Posts
    71

    Re: Printdocument doesn't print icon

    Thanks for the advice.
    I decided to leave out the color code,since I don't need it for my purpose.

  7. #7
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,043

    Re: [RESOLVED] Printdocument doesn't print icon

    Usually, when I see this, it is as JMC said: It IS drawing, it just isn't drawing where you expect it to be drawing, so you can't see it. In my case, that is usually because I'm using the wrong coordinates. I'm either drawing relative to the control or relative to the form, and get it backwards. After all, if you are drawing in form coordinates and expecting the image to show up in a control on the form...it probably won't. Fortunately, there are times when it will, which usually alerts you to what is going on. That seems unlikely, in this case, though, because the target area to which you are drawing seems so small that getting part of something into that area by accident seems pretty unlikely.

    The first thing to do is to look at the coordinates that are actually being drawn to at runtime. In this case, that looks like just TextRect. While you are in there, you might also want to look at the color. It would be kind of frustrating to find out that it really WAS drawing, but the color you thought you were drawing wasn't the color you were actually drawing. Drawing black on black, for example, might draw in the right place but you'd never know, so just check that the color you are drawing is distinct enough that you would actually see it. You're doing something weird with those colors, currently, so that might be an issue. After all, you take a color as an integer, then pass it through a translator to turn it back into a color. What color does it get turned back into? Hopefully, not the color that it already was, because that would be a waste of time. If it's some other color, is it some other color that is visible on the background?

    Still, the more likely answer is that TextRect is not what you were thinking it would be.
    My usual boring signature: Nothing

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width