Adding images into next available picturebox - vb.net

I'm doing a deck builder project through a card database and so far when I click a row (using datagridview), the value contained in the "image_url" column is printed into an invisible textbox, which is then used to download that image and show it in a picturebox.
Now that all works fine, but decks go up to 60 cards so I'm going to use 60 pictureboxes to print the user's selected cards. What I'm been trying to do is set up like a picturecount and when they select a column the number is increased by one like this:
picturebox(picturecount) = textbox4.text
but I've run into too many errors. Would you know a way to display the user's selected card in the next available picturebox? For example if they select "Dark Magician" three times, then the image of the "Dark Magician" is printed in the first available three pictureboxes
VB.NET:
Private Async Sub PictureLoader()
Dim imageURL As String
If TextBox4.Text = "" Then
imageURL = dataSet.Tables("YGO cards").Rows(row_count).Item(7)
Else
imageURL = TextBox4.Text
End If
Dim client As Net.WebClient = New Net.WebClient()
Dim ms As MemoryStream = New MemoryStream(Await client.DownloadDataTaskAsync(New Uri(imageURL)))
Using image As Image = Image.FromStream(ms)
PictureBox1.Image?.Dispose()
PictureBox1.Image = DirectCast(image.Clone(), Image)
End Using
ms.Dispose()
client.Dispose()
End Sub
and this is the event when a column is selected in the datagrid!
Dim index As Integer
index = e.RowIndex
Dim selectedrow As DataGridViewRow
selectedrow = DataGridView1.Rows(index)
' selectedrow.Cells(1) is the image_Url column
TextBox4.Text = selectedrow.Cells(1).Value.ToString()
If TextBox4.Text = "" Then
PictureBox1.Image = Nothing
' imageURL = dataSet.Tables("YGO cards").Rows(row_count).Item(7)
Else
PictureLoader()
End If

Ignore for a moment the specifics of your particular problem and break this down into a generic statement. What you're saying is that you have a collection and that the size of the collection can grow or shrink based on user input. This is an ideal case for a List(Of T) where you declare the List by specifying the data type of the items it will hold and then add items as needed. Because you are storing the URL of the card, you would create a new List(Of String):
Dim cards As List(Of String) = New List(Of String)
Now whenever you needed to add URLs to your list you would call the Add method if it is a single URL or AddRange if it is multiple URLs:
cards.Add(TextBox1.Text)
'Or
cards.AddRange({TextBox1.Text, TextBox2.Text, TextBox3.Text})
As far as displaying the image in the PictureBox, there's really no need to create a MemoryStream and clone an Image considering that the PictureBox class has the Load and LoadAsync (which it looks like you want asynchronous capabilities) methods. But if you wanted to create a PictureBox for every item in your collection, you will need to iterate through the collection, create a new PictureBox, call the Load or Load Async method on the currently iterated URL, and then add it to the Form (or a container in general). This can be done using a traditional For/Each loop:
'Create a placeholder variable
Dim cardPictureBox As PictureBox
'Loop through every selected card URL
For Each url As String In Cards
'Create a new PictureBox
cardPictureBox = New PictureBox() With {
.Size = New Size(100, 100)
.SizeMode = PictureBoxSizeMode.CenterImage
.WaitOnLoad = False
}
'Add the PictureBox to the Form
Me.Controls.Add(cardPictureBox)
'Load the image asynchronously
cardPictureBox.LoadAsync(url)
Next

Related

VB.NET 2019 How to populate a Tag Property on a dynamic ToolstripmenuItem

I am struggling to populate a tag property on a dynamically created sub menu which I have created. I have a text file that contains a number of radio station names, BBC1, BBC2, BBC3 for example, as well as the associated stream addresses for said stations. I am able to pull in the names and apply it to the submenu. They appear fine. I can click on the submenus, and the sender() variable confirms the station names correctly. My problem is that I cannot get the Tag property for each sub menu/radio station, to store the stream address. The code gets the radio title cleans the code and inserts it into the RadioStreamsToolStripMenuItem.DropDownItems.Add(station_name) and all is fine. The code then gets the Stream address and inserts it here RadioStreamsToolStripMenuItem.Tag.ToString(). I can tell that it is wrong, but how do I go about ensuring the correct stream goes into the correct radio Tag property. Im very new to this so please be gentle, its just a little hobby.
'======================================================================
'Aquires Radio name and creates a dropdown sub menu within RadioStreams
'======================================================================
Do While (Not line Is Nothing)
If line.StartsWith("#") Then
station_name = Replace(line, "#", "")
Dim x = RadioStreamsToolStripMenuItem.DropDownItems.Add(station_name)
AddHandler x.Click, AddressOf ToolMenuItem_Click
'===================================================
'Aquires Radio Stream to add to the Tag property for each new station
'===================================================
ElseIf line.StartsWith("#") Then
Dim station_stream As String = Replace(line, "#", "")
'The following just checks if the data has gone into the correct place
For Each Myitem As ToolStripItem In RadioStreamsToolStripMenuItem.DropDownItems
If Myitem.Text = station_name Then
MsgBox("MyItems " & Myitem.ToString())
Me.Tag = station_stream
End If
Next
You could use a Dictionary to store the stations a stream addresses. Dictionary lookups are very fast.
I assumed from your code that your text file looks like this
#BBC1
#BBC1streamAddress
#BBC2
#BBC2streamAddress
#BBC3
#BBC3streamAddress
I looped through the lines of the file assigning the trimmed keys and values to the dictionary. Then looped through the dictionary filling the menu. When the user clicks a menu item we get the text of the item and search the dictionary for the correct stream address.
Private RadioDictionary As New Dictionary(Of String, String)
Private Sub OPCode()
Dim lines = File.ReadAllLines("Radio.txt")
For i = 0 To lines.Length - 1 Step 2
RadioDictionary.Add(lines(i).Trim("#"c), lines(i + 1).Trim("#"c))
Next
For Each item In RadioDictionary
Dim x = RadioStreamsToolStripMenuItem.DropDownItems.Add(item.Key)
AddHandler x.Click, AddressOf ToolMenuItem_Click
Next
End Sub
Private Sub ToolMenuItem_Click(sender As Object, e As EventArgs) Handles ToolMenuItem.Click
Dim station = DirectCast(sender, ToolStripDropDownItem).Text
Dim stream = RadioDictionary(station)
End Sub

Winnovative Hides Text of TextElements on PDFs

There is a group somewhere in our organization that scans documents and converts them to PDFs. They then associate those PDFs with an "event" record and store them in a database. On demand, my application -- which uses Winnovative HTML to PDF v9.0.0.0 -- has to retrieve the PDFs associated with an event, place a header on the first page of each, and store them on the file system. This header is a TextElement.
On some PDFs, the header displays beautifully. On others, the header does not appear. However, when viewing the PDF, the header can be "highlighted" with the cursor and its text successfully copied, so the header is indeed present and properly positioned. (See the green arrow in the inserted image.)
I have identified two PDFs that were scanned by the same person thirty minutes apart and associated with the same event in the database. On one, the header is displayed; on the other, it is not. To investigate, I have set the BackColor of the TextElement to Crimson. The Text appears and doesn't appear as before, but the TextElement always appears bright red.
The properties of the two Document and PDFPage objects are identical, including the TransparencyEnabled property. This phenomenon is present in PDFs of all sorts of documents scanned by various people over time. And it's not just this header TextElement, but TextElements everywhere on the PDF (e.g. Page X of Y, watermarks). On a given PDF, if the Text of one is visible, the Text of all is visible, and vice versa.
I can find no pattern or explanation. What could be causing some PDFs to "hide" the Text (and only the Text) of all TextElements that I put on them while others don't?
Private Sub AddTitleToFirstPage(ByRef pdf As Document)
Dim headerSystemFont As New Font("Arial", 10)
Dim headerFont As PdfFont = pdf.Fonts.Add(headerSystemFont)
Dim headerTextElement As New TextElement(65, 20, "My Page Title", headerFont)
headerTextElement.TextAlign = HorizontalTextAlign.Center
headerTextElement.ForeColor = Color.DarkBlue
headerTextElement.BackColor = Color.Crimson
pdf.Pages(0).AddElement(headerTextElement)
End Sub
Friend Function UpdatePdfDoc(pdfBytes As Byte()) As Byte()
Dim bytes As Byte()
Using docStream As New MemoryStream(pdfBytes, 0, pdfBytes.Length)
Dim returnDoc As Document = New Document(docStream)
returnDoc.LicenseKey = WinnovativeLicenceKey
AddTitleToFirstPage(returnDoc)
bytes = returnDoc.Save()
docStream.Close()
End Using
Return bytes
End Function
Friend Function GetEventObjectPdfSource(scannedDocIds As List(Of String)) As Object
Dim scannedDocObjectPdfSourceList As New List(Of Byte())()
For Each scannedDocId As String In scannedDocIds
Dim scannedDocObjectPdfSource As Byte() = GetScannedDocBlobById(scannedDocId)
scannedDocObjectPdfSource = UpdatePdfDoc(scannedDocObjectPdfSource)
scannedDocObjectPdfSourceList.Add(scannedDocObjectPdfSource)
Next
Return scannedDocObjectPdfSourceList
End Function
Friend Function GetEventObjectPdf(eventId As String) As String
Dim pdfFileName As String = GetPDFFileName(eventId)
Dim scannedDocIds As List(Of String) = GetScannedDocumentsForEvent(eventId)
Dim objectPdfSourceList As List(Of Byte()) = CType(GetEventObjectPdfSource1(scannedDocIds), List(Of Byte()))
For Each objectPdfSource As Byte() In objectPdfSourceList
Using docStream As New MemoryStream(objectPdfSource, 0, objectPdfSource.Length)
Dim masterDoc As New Document(docStream)
masterDoc.LicenseKey = WinnovativeLicenceKey
Do While masterDoc.Bookmarks.Count > 0
masterDoc.Bookmarks.Remove(0)
Loop
Try
masterDoc.AutoCloseAppendedDocs = True
masterDoc.Save(pdfFileName)
Catch ex As Threading.ThreadAbortException
Threading.Thread.ResetAbort()
Finally
masterDoc.DetachStream()
masterDoc.Close()
End Try
docStream.Close()
End Using
Next
Return pdfFileName
End Function
Please forgive the clunky code. I didn't write it. I just inherited it.

Using Listview to insert an image in one column and write in another in vb

I have a listview with three column named: picture, time, description.
I need to add an image to the first column and at then add time and description to the other but in the same row.
I had a look on the internet and managed to find a code that adds the images to the listview. This is shown below:
Dim imagelist As ImageList = New ImageList()
imagelist.ImageSize = New Size(10, 10)
imagelist.Images.Add(Bitmap.FromFile("0.png"))
imagelist.Images.Add(Bitmap.FromFile("1.png"))
imagelist.Images.Add(Bitmap.FromFile("2.png"))
imagelist.Images.Add(Bitmap.FromFile("3.png"))
imagelist.Images.Add(Bitmap.FromFile("4.png"))
imagelist.Images.Add(Bitmap.FromFile("5.png"))
LV_Log.Items.Add("", 5)
LV_Log.SmallImageList = imagelist
Now I have a code that added text to the columns.
Dim lvi As New ListViewItem
lvi.Text = "image"
lvi.SubItems.Add(Now())
lvi.SubItems.Add(message)
LV_Log.Items.Add(lvi)
Here I want to add an image where it says "image".
Assuming the ListView's imageList property is set to the correct image list you can do something like this.
Dim newItem As ListViewItem = New ListViewItem
newItem.ImageIndex = 0 'or look for correct one from image list
newItem.SelectedImageIndex = 0 'if the image should change
newItem.Text = Now()
newItem.SubItems.Add("description") 'may need to play here, haven't done this in a while

Retrieving images from a database?

I'm new to the forums and wanted to ask a question that has been bugging me for ages. I am using Visual Studio express 2012 with Windows Forms.
I want to have a database consisting of different images. Each row has its own image, and the other fields in the row define the images characteristics (I.E. Colour = Red, Striped = Yes etc) and its own specific ID.
Now what I want to do is allow the user to search via the form (Selecting what characteristics they want the image to have based on options on the form and then using SQL statements to retrieve the images based on their inputs). The only issue I am having is displaying all of the images on the form when they have searched? Is there any idea as to how to do this dynamically?
I created a form with FlowLayoutPanel in it. I set its AutoScroll property to true so that if there more pictures than fit in the space, it'll show a scroll bar so you can see them all.
I'm not entirely sure how you're getting the image, but assuming you have a function that returns a list of images.
Private Function DoImageSearch(parameters As SearchParameters) As List(Of Image)
'Go get images from database
End Function
Then you could have a function like the following to dynamically create PictureBox controls to be added to the FlowLayoutPanel.
Private Sub DynamicallyCreatedPictureBoxes(images As List(Of Image))
For Each image In images
Dim picture = New PictureBox()
picture.Image = image
picture.Size = image.Size
FlowLayoutPanel1.Controls.Add(picture)
Next
End Sub
In this case I've set the size of the PictureBox to be the size of the image. You may want to try to scale them or make thumbnails, but I'll leave that up to you (or another question). You'd probably also want another method to clear the images.
Private Sub ClearPictureBoxes()
FlowLayoutPanel1.SuspendLayout()
For Each control As Control In FlowLayoutPanel1.Controls
control.Dispose()
Next
FlowLayoutPanel1.Controls.Clear()
FlowLayoutPanel1.ResumeLayout()
End Sub
I'm not confident that last method is entirely correct, but you'd probably want something close to it.
Try like the this,
If color_RadioButton.Checked = True and type_RadioButton.Checked = True Then
cmdTect="color='" & color_RadioButton.Text & "' and type='" & type_RadioButton.Text & "'"
ElseIf color_RadioButton.Checked = True and type_RadioButton.Checked = False Then
cmdTect="color='" & color_RadioButton.Text & "'"
ElseIf color_RadioButton.Checked = False and type_RadioButton.Checked = TrueThen
cmdTect="type='" & type_RadioButton.Text & "'"
End If
dim cmd as new sqlcommand("select count(photo) from tbl where " & cmdTect,conn)
dim cnt as integer=cmd.ExecuteScalar()
for i as integer=0 to cnt
cmd = New SqlCommand("select photo from tbl where" & cmdTect,conn)
Dim imageData As Byte() = DirectCast(cmd.ExecuteScalar(), Byte())
If Not imageData Is Nothing Then
Dim ms As New MemoryStream(imageData, 0, imageData.Length)
ms.Write(imageData, 0, imageData.Length)
Dim pic As New PictureBox
pic.BackgroundImage = Image.FromStream(ms, True)
Panel1.Controls.Add(pic)
End If
Next

Loading the ImageList to ListView doesn't work as intended in vb.net 2010

I try to load images from ImageList to ListView and it works great... but when the form is load, the last image of ImageList doesn't appear.... I will call this procedure at the combobox selectedIndexChanged event and at the form load... when the form load, the last image from ImageList doesn't appear and when I click the combobox for several times, all of the images appear as intended... Any help?
Here is the code..
Private Sub LoadMenuItem()
lvItem.Clear()
Dim adptItem As New Restaurant_Management_SystemDataSetTableAdapters.ItemTableAdapter
Dim categoryID As Integer = cboccategory.SelectedValue
Dim dtItem As Restaurant_Management_SystemDataSet.ItemDataTable = adptItem.GetDataByCategoryID(categoryID)
lvItem.BeginUpdate()
For Each drItem As Restaurant_Management_SystemDataSet.ItemRow In dtItem.Rows
Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream(drItem.ImageForItem)
Dim img As Image = System.Drawing.Image.FromStream(ms)
ImageList1.Images.Add(drItem.ItemID, img)
lvItem.Items.Add(drItem.ItemName.Trim, drItem.ItemID)
Next
lvItem.EndUpdate()
cboItem.ValueMember = "ItemID"
cboItem.DisplayMember = "ItemName"
cboItem.DataSource = dtItem
lvItem.Refresh
End Sub