Print multiple images in vb.net - vb.net

In VB.NET, I need to print multiple Images of bar codes by arranging them in tabular format. For now what I am doing is, Creating the bar codes and adding them in new picture box. These Picture boxes are added on a panel which I am creating on form at run time and print that panel (with picture boxes in 4x9 table).
But, when I need to print more that 36 bar codes, this idea doesn't work.
So, Please suggest me some improvements in my code or any other way to do this job.
I am sorry, here is the code for generating images and adding them to the panel..
''' Method for create bar code images with a loop and adding them to the panel by picture box...
Private Function GetBarcodeText(RowId As Guid)
Dim BarcodeValue As StringBuilder = New StringBuilder(96)
Dim temp As New StringBuilder
Dim data As String
Dim param = New SqlParameter()
Dim imageNo As Integer = 0
Dim colorValue As String = ""
Dim scaleValue As String = ""
'' Adding the panel on the form which is dynamically created
Me.Controls.Add(outputPanel)
'' Setting the Initial size for the panel
outputPanel.Size = New Point(794, 112)
outputPanel.Name = "outputPanel"
outputPanel.BackColor = Drawing.Color.White
param.ParameterName = "#RowId"
param.Value = RowId
param.SqlDbType = SqlDbType.UniqueIdentifier
' Get the particular row of data from database
dt = objStockProvider.GetBarcodeDetails(param)
' GET colour code
Dim color As String = dt.Rows(0)("COLOUR").ToString()
Dim countColors As Integer = 0
' Get the color code numbers
param.ParameterName = "#Dscale"
param.Value = dgvViewTickets.CurrentRow.Cells("SCALE").Value.ToString()
countColors = objStockProvider.CountColorCodes(param)
For i = 1 To countColors
For j As Integer = 1 + ((12 / countColors) * (i - 1)) To (12 / countColors) * i
If dt.Rows(0)("S" + j.ToString()) <> 0 Then
Dim totalTicketsForASize As Integer
totalTicketsForASize = dt.Rows(0)("S" + j.ToString())
For k As Integer = 1 To totalTicketsForASize
' Set Bar code value which has to create
BarcodeValue = "123456789012"
' Create Barcode Image for given value
Dim image = GetBarcodeImage(BarcodeValue, colorValue, scaleValue)
If image IsNot Nothing Then
'' Create picture box to contain generated Image.
Dim pcbImage As New PictureBox
pcbImage.Width = W
pcbImage.Height = H
pcbImage.Image = image
pcbImage.Location = New Point(X, Y)
imageNo += 1
If imageNo Mod 4 = 0 Then
X = 15
Y += H
outputPanel.Height += H
Else
X += W
Y = Y
End If
pcbImage.Visible = True
'' Adding picture box to panel
outputPanel.Controls.Add(pcbImage)
End If
Next
End If
Next
color = color.Substring(color.IndexOf(",") + 1, color.Length - color.IndexOf(",") - 1)
Next
PrintGeneratedTickets()
End Function
Now, I am printing the panel by following method:
Private Sub PrintGeneratedTickets()
bmp = New Bitmap(outputPanel.DisplayRectangle.Width, outputPanel.DisplayRectangle.Height)
Dim G As Graphics = Graphics.FromImage(bmp)
G.DrawRectangle(Pens.White, New Rectangle(0, 0, Me.outputPanel.DisplayRectangle.Width, Me.outputPanel.DisplayRectangle.Height))
Dim Hdc As IntPtr = G.GetHdc()
SendMessage(outputPanel.Handle, WM_PRINT, Hdc, DrawingOptions.PRF_OWNED Or DrawingOptions.PRF_CHILDREN Or DrawingOptions.PRF_CLIENT Or DrawingOptions.PRF_NONCLIENT)
G.ReleaseHdc(Hdc)
pndocument.DocumentName = bmp.ToString()
Dim previewmode As New PrintPreviewDialog
previewmode.Document = pndocument
previewmode.WindowState = FormWindowState.Maximized
previewmode.PrintPreviewControl.Zoom = 1
pndocument.DefaultPageSettings.Margins.Top = 10
pndocument.DefaultPageSettings.Margins.Bottom = 30
pndocument.DefaultPageSettings.Margins.Left = 16
pndocument.DefaultPageSettings.Margins.Right = 16
pndocument.DefaultPageSettings.Landscape = False
' Set other properties.
previewmode.PrintPreviewControl.Columns = 4
previewmode.PrintPreviewControl.Rows = 9
previewmode.ShowDialog()
Dim file As String = DateTime.Now.ToString()
file = Path.GetFullPath("D:\Bar Codes\" + file.Replace("/", "-").Replace(":", ".") + ".bmp")
bmp.Save(file)
G.Dispose()
outputPanel.Controls.Clear()
End Sub
This code is working fine but what I need to do, is to fix the number of images (4x9) per page. But when I am trying to create more than it, that all are printing on a single page with compressed size.
Also when trying to re-run the code, It shows nothing in preview..
Some body please suggest the correction in code so that I can reprint the tickets and use paging for more than 36 images.

Well, Printing the Images on a panel was not a good idea.. I replaced the panel and created an array of images and used the print document directly and print after arranging images on it.
Thanks.

Related

Top value for generated picturebox isn't correctly adding

I'm using this code:
For Each srvr In discord.Guilds
Dim top As Integer = 30
Dim pb As New PictureBox
pb.Width = 70
pb.Height = 70
pb.Left = 10
pb.Top = top
top = +30
pb.Cursor = Cursors.Hand
Dim ttImage As Bitmap = Bitmap.FromStream(New MemoryStream(tClient.DownloadData(srvr.IconUrl)))
pb.BackgroundImage = ttImage
pb.Tag = srvr.Id.ToString + " | " + srvr.Name
pb.BackgroundImageLayout = ImageLayout.Zoom
Me.Controls.Add(pb)
pb.BringToFront()
Next
The problem is, I have no clue why the top value doesn't place the Pictureboxes lower. I've tried doing top += 30 as well, not working at all. How can I make this work?
What I would recommend is using a FlowLayoutPanel.
Create the panel on your form, and size it to the area you want to show the icons. Then, when you want to add a picturebox to it, do this:
Dim pb As New PictureBox
pb.Width = 70
pb.Height = 70
Dim ttImage As Bitmap = Bitmap.FromStream(New
MemoryStream(tClient.DownloadData(srvr.IconUrl)))
pb.BackgroundImage = ttImage
pb.Tag = srvr.Id.ToString + " | " + srvr.Name
pb.BackgroundImageLayout = ImageLayout.Zoom
FlowLayoutPanel1.Controls.Add(pb)
Notice how you don't need to specify the location. This is because the FlowLayoutPanel automatically calculates where the control should be placed.
If, however, you want to stick to your current method, the issue I noticed is that the Top variable is being declared within the for loop. This means every loop it makes, the old variable goes out of scope, and a new one is declared. So in short, since the variable is declared inside the for loop, nothing you do to it will pass over outside the loop, or in the next iteration of the loop, since it's a different variable.
Also, the correct syntax is
Top += 30
This should fix your issue:
Dim TopSpacer As Integer = 30
For Each serval In Discord.Guilds
Dim PBico As New PictureBox With {.Size = New Size(70, 70),
.Location = New Point(10, TopSpacer)}
Dim WebClient As New WebClient
Dim ImageBytes() As Byte = WebClient.DownloadData(serval.IconUrl)
Dim IMG As Image = Image.FromStream(New IO.MemoryStream(ImageBytes))
PBico.Image = IMG
Me.Controls.Add(PBico)
TopSpacer = TopSpacer + 100
Next
In the code above, the 'Top' variable will be the same variable for each of the loops, because it is not within the loop's inner scope.

Arranging Buttons inside a Panel vb.net

I am trying to put 25 Buttons inside a Panel in VB.Net 2015 Classic Form Like the Picture but it is not working . could you please help... bellow my code
Dim i As Integer
For i = 1 To 25
newButton = New Windows.Forms.Button
newButton.AutoSize = True
newButton.Name = "btnButton" & i
newButton.Text = "Button " & i
newButton.Top = i * 5
newButton.Left = i * 25
newButton.Size = New Size(95, 70)
AddHandler newButton.Click, AddressOf ButtonClicked
Panel1.Controls.Add(newButton)
Next
Your code is creating the buttons, and the problem is that they are not arranged properly so what you need to do is arrange them in rows and columns. here i help you to do this;
Here this snippet will tell you how to arrange them in 5 columns and n rows:
Dim x As Integer = 5 ' x co-ordinate of the point
Dim y As Integer = 5 ' y co-ordinate of the point
For i = 1 To 25
If i Mod 5 = 0 Then ' For starting next row after column
y += 100 ' 100 is not mandatory change as per size of button
x = 0
Else
x += 100 ' 100 is not mandatory change as per size of button
End If
Dim p As Point = New Point(x, y)
Dim newButton = New Windows.Forms.Button
newButton.Location = p
//do the rest of formatting here
Panel1.Controls.Add(newButton)
Next

VB.net Adding Picturebox with Label and Scrollbar dynamically

So basically what I wish to accomplish is that I set total of Pictureboxes to add and each picturebox has its own according label and if we reach 6 images we allow the scrollbar to go down.
Example:
http://i.imgur.com/5xWu5Y1.png
As you can see pictures are added accordingly with label.
How can I do this in code?
Currently I got something like this:
' Total PictureBoxes/Labels to Generate
Dim wTotalPictures = 1
' Original PictureBox Starting Point
Dim wOriginalLocation = New System.Drawing.Point(40, 54)
' Assigned Label Title
Dim wImageTitle As String = "PictureTitle"
Dim wNewImage As New PictureBox
Dim wImageSize = New Size(122, 173)
With wNewImage
.SizeMode = PictureBoxSizeMode.StretchImage
.Image = Image.FromFile("C:\Users\Jason\Pictures\newImage.jpg")
.Location = wOriginalLocation
.Size = wImageSize
End With
So any help would be greatly appreciated!
EDIT:
I've now managed to change it into this, this works way better but still not 100% automatic like I want it.
' Total PictureBoxes/Labels to Generate
Dim i As Integer = 0
Dim wTotalPictures = 5
' Original PictureBox Starting Point
Dim wOriginalLocation = New System.Drawing.Point(40, 54)
' Assigned Label Title
Dim wImageTitle As String = "PictureTitle"
Dim wImageSize = New Size(122, 173)
Dim wNewLocation As Integer = 0
Do Until i = wTotalPictures
' Setup
Dim wNewImage(i) As PictureBox
wNewImage(i) = New PictureBox
' Execute
wNewImage(i).SizeMode = PictureBoxSizeMode.StretchImage
wNewImage(i).Image = Image.FromFile("C:\Users\Jason\Pictures\newImage.jpg")
wNewImage(i).Size = wImageSize
If wNewLocation < 480 Then
wNewImage(i).Location = New System.Drawing.Point(40 + wNewLocation, 54)
ElseIf wNewLocation = 480 Then
wNewImage(i).Location = New System.Drawing.Point(40, 258)
wNewLocation = 0
End If
' Add to Form
MyTab.Controls.Add(wNewImage(i))
wNewImage(i).BringToFront()
wNewLocation = wNewLocation + 160
i += 1
Loop
Please help, thanks!

ReportViewer.LocalReport.Render("PDF")

I am using Report Viewer for WinForms. The problem i am having is this: I have a form that contains a form which is used to view a local report which work fine, but when I try to render the same report as a PDF, it is cut-off, but in report viewer the same report renders a report on one page. When I render to PDF it cuts it off and the part of the report that was cut-off renders on a 2nd page. So in other words, part of the same report is on page 1, and 2nd half is on 2nd page in the PDF?
Code:
Private Function GetPDfReport() As String
Dim parameters = Me.GetReportParms()
Dim query = Me.GetReportQuery()
Dim rView As Microsoft.Reporting.WinForms.ReportViewer = New Microsoft.Reporting.WinForms.ReportViewer
rView.Dock = DockStyle.Fill
rView.SetDisplayMode(DisplayMode.PrintLayout)
Dim pnl As New Panel()
pnl.Name = "pnlMain"
pnl.Location = New System.Drawing.Point(0, 25)
pnl.Size = New System.Drawing.Size(734, 478)
pnl.Controls.Add(rView)
Dim dbReader As New dbReader()
Dim ds As DataSet = dbReader.DataSet(query)
Dim rds As Microsoft.Reporting.WinForms.ReportDataSource = New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", ds.Tables(0))
rView.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local
rView.LocalReport.DataSources.Add(rds)
rView.LocalReport.ReportEmbeddedResource = "EasyDose.rptIncident.rdlc"
If Not IsNothing(parameters) Then
Dim Bound0 As Integer = parameters.GetUpperBound(0)
Dim Bound1 As Integer = parameters.GetUpperBound(1)
For index = 0 To Bound0
Dim rParameter As New ReportParameter(parameters(index, 0), parameters(index, 1))
rView.LocalReport.SetParameters(rParameter)
Next
End If
Dim ps As PageSettings = rView.GetPageSettings
ps.Margins.Top = 0 ' 10mm approx
ps.Margins.Right = 0
ps.Margins.Bottom = 0
ps.Margins.Left = 0
ps.Landscape = False
'ps.PaperSize = New PaperSize("LetterExtra", (9.275 * 100), (12 * 100)) ' Letter paper (8.5 in. by 11 in.) ' Letter extra paper (9.275 in. by 12 in.)
ps.PaperSize = New PaperSize("A4", (8.27 * 100), (11.69 * 100))
rView.RefreshReport()
Dim exePath As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath)
Dim dir As New DirectoryInfo(System.IO.Path.Combine(exePath, "tmpDir"))
Dim file As New FileInfo(System.IO.Path.Combine( _
dir.FullName, String.Format("Patient_Details_{0:yyyyMMdd_hhmmss}.pdf", DateTime.Now)))
If Not dir.Exists Then
dir.Create()
End If
Dim bytes As Byte() = rView.LocalReport.Render("PDF")
Using fs As New System.IO.FileStream(file.FullName, System.IO.FileMode.Create)
fs.Write(bytes, 0, bytes.Length)
fs.Close()
End Using
Return file.FullName
End Function
are you seeing the local report in the embedded ReportViewer using the "Print Layout" option activated? That should show exactly the same output as your printed result.
If you have problems in the PDF is probably caused by the design of the report itself. Check the font, the page size and orientation, the margins, the page breaks.
uisng System.IO;
byte[] rep = reportViewer1.LocalReport.Render("pdf", deviceInfo: "");
// if a certificate warning appears just ignore and re-run
File.WriteAllBytes(filepath+filename+".pdf",rep);

multiple DatagridView Rendering Vb.net

I'm able to add multiple datagridview 1 after another on panel.
by adding code of SysDragon from the same forum
Dim AllDataGrids As List(Of My_custom_DGV)
Dim lastCtrl As Control
AllDataGrids = New List(Of My_custom_DGV)
For j As Int32 = 0 To 3
Dim aDataGridView As New My_custom_DGV()
aDataGridView.for_date = ""
aDataGridView._count = week_count
aDataGridView.Dock = DockStyle.Top
aDataGridView.Dock = DockStyle.Right
aDataGridView.Dock = DockStyle.Left
aDataGridView.Dock = DockStyle.Bottom
AllDataGrids.Add(aDataGridView)
Next j
For i As Integer = 1 To 3
Dim dgv As My_custom_DGV = AllDataGrids(i)
' Dim dgv As DataGridView = AllDataGrids(i)
If dataGrid_Panel.Controls.Count.Equals(0) Then
dgv.Top = DataGridView1.Height + 20
Else
lastCtrl = dataGrid_Panel.Controls(dataGrid_Panel.Controls.Count - 1)
dgv.Top = lastCtrl.Top + lastCtrl.Height + 5
End If
dataGrid_Panel.Controls.Add(dgv)
Next
the problem is that when i scroll in between them then it is looking very bad(i.e. as i scroll,it is repeating the the image on panel again and again). does it render the view again when i Scroll,and may be calling the paint method of datagridview repeatedly. if yes then what is the solution?
Thanks.