-
Apr 15th, 2021, 04:30 AM
#1
Thread Starter
Lively Member
[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
-
Apr 15th, 2021, 05:19 AM
#2
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.
-
Apr 15th, 2021, 10:31 AM
#3
Thread Starter
Lively Member
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.
-
Apr 15th, 2021, 12:48 PM
#4
Thread Starter
Lively Member
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
-
Apr 15th, 2021, 07:03 PM
#5
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.
-
Apr 16th, 2021, 10:16 AM
#6
Thread Starter
Lively Member
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.
-
Apr 16th, 2021, 11:18 AM
#7
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|