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!
Related
I have a from which contains some PictureBoxes. They can be from one to many.
I create them at run-time depending on the existence of specific folders.
I create them and place them the one next to each other. This means that with a scrollable form I can view all of them easy.
My question is this: How do I position them in "rows"? For a specific form size, there can be 5 labels next to each other and infinite rows of them
How do I achieve this?
My (working) code:
Public allSeries As IEnumerable(Of String) = System.IO.Directory.EnumerateDirectories(root)
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox With {
.Name = "pb" & i.ToString,
.Size = New Drawing.Size(500, 500),
.Location = New Point(5, 5),
.BorderStyle = BorderStyle.FixedSingle,
.SizeMode = PictureBoxSizeMode.Zoom,
.Image = Image.FromFile(allSeries(i - 1).ToString + "\sImage.jpg"),
.Tag = traveldestination, 'Store Directory path
.Cursor = Cursors.Hand}
Me.Controls.Add(pb)
For i As Integer = 2 To allSeries.Count
With Me
.Controls.Item("pb" + i.ToString).Left = .Controls.Item("pb" + (i - 1).ToString).Left + 520
End With
Next
My (bad) and (not workng) code:
Dim pbsOnForm As Integer = 13 'total PictureBoxes on Form /for this instance
Dim pbsOnRow As Integer = 5 'PictureBoxes that "fit" in a row /for this intance)
For i As Integer = 1 To pbsOnForm
If i <= pbsOnRow Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + i.ToString).Top
End If
If i > pbsOnRow And i <= 10 Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + (i - pbsOnRow).ToString).Top
End If
Works, but when the PcrureBoxes will be more than 10, I do not know......
While using the TableLayoutPanel would fulfill most cases for this and is probably the best way to achieve this, here is some code to align the PictureBox's in row / column.
First we want to setup a method to handle the positioning. We need some variables scoped to the Form.
Dim counter As Integer = 0
Dim xPos As Integer = 5
Dim yPos As Integer = 5
Now we use these variables in a method that sets the location.
Private Sub PositionPictureBox(pb As PictureBox, Optional imgPerRow As Integer = 5)
pb.Location = New Point(xPos, yPos)
counter += 1
If counter = imgPerRow Then
counter = 0
xPos = 5
yPos = pb.Location.Y + pb.Height + 5
Else
xPos = pb.Location.X + pb.Width + 5
End If
End Sub
Finally we call the method when the PictureBox is instantiated.
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox
With pb
.Name = "pb" & i.ToString()
.Size = New Drawing.Size(50, 50)
.Location = New Point(5, 5)
.BorderStyle = BorderStyle.FixedSingle
.SizeMode = PictureBoxSizeMode.Zoom
.Image = Image.FromFile("...")
.Tag = allSeries(i)
.Cursor = Cursors.Hand
End With
PositionPictureBox(pb)
Me.Controls.Add(pb)
Next
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.
I simply want to add three controls to my form. The first two show up, but the third does not. I do not understand why this behavior is happening. I have tried using .bringToFront(), but I end up with the same results. I also tried using Me.controls.setChildIndex() but that does not help either.
I am at a loss. I must be doing something wrong. Please help.
Thanks.
This is my code:
' Add the label
' ------------------
Dim menu_label As New Label
menu_label.Text = "Menu"
menu_label.Location = New Point(50, 20)
menu_label.Width = 50
menu_label.Font = New Font(main_font, main_font_size, FontStyle.Regular)
menu_label.ForeColor = Color.White
Me.Controls.Add(menu_label)
' create the image
' ---------------
Dim logo As New PictureBox
Dim logo_image As Image
logo_image = My.Resources.logo
logo.Image = logo_image
logo.Width = 30
logo.Height = 30
logo.Left = 5
logo.Top = 0
Me.Controls.Add(logo)
' add a line
' ----------
Dim line As New Panel
line.Height = 1
line.Width = Me.Width
line.BackColor = Color.Red
line.Location = New Point(0, 32)
Me.Controls.Add(line)
' end code
' ---------------------------------
Only the first two items show up no matter which order I put them in. So I either get just the logo and the menu label, or just the logo and the line, or just the line and the menu label. It's nuts!
So I tried:
Me.Controls.SetChildIndex(logo, 0)
Me.Controls.SetChildIndex(menu_label, 1)
Me.Controls.SetChildIndex(line, 2)
Whichever item gets assigned to level 2 never shows up.
I also tested and it worked fine for me. Changed the form backcolor to black so you can see the results better:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' Add the label
' ------------------
Dim menu_label As New Label
menu_label.Text = "Menu"
menu_label.Location = New Point(50, 20)
menu_label.Width = 50
'menu_label.Font = New Font(main_font, main_font_size, FontStyle.Regular)
menu_label.ForeColor = Color.White
Me.Controls.Add(menu_label)
' create the image
' ---------------
Dim logo As New PictureBox
Dim logo_image As Image
'logo_image = My.Resources.logo
'logo.Image = logo_image
logo.BackColor = Color.Yellow
logo.Width = 30
logo.Height = 30
logo.Left = 5
logo.Top = 0
Me.Controls.Add(logo)
' add a line
' ----------
Dim line As New Panel
line.Height = 1
line.Width = Me.Width
line.BackColor = Color.Red
line.Location = New Point(0, 32)
Me.Controls.Add(line)
Me.BackColor = Color.Black
End Sub
What else is on your form? Perhaps you could post a screenshot?
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.
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.