VB.NET: DataGridViewImageCell - Image from Ressource? - vb.net

I have added a datagridview on a windows form with the name DataGridView1. The following code adds a row with 2 columns. I want to show an image in the 2nd column.
Dim dt As New DataTable
dt.Columns.Add("TESTROW")
dt.Rows.Add("TESTCONTENT")
DataGridView1.DataSource = dt
Dim colImage As New DataGridViewImageColumn
DataGridView1.Columns.Add(colImage)
For intI As Integer = 0 To dt.Rows.Count
Dim cellImage As New DataGridViewImageCell
' THE FOLLOWING LINE WORKS FINE!!!!
cellImage.Value = Drawing.Image.FromFile("c:\foo\bar.gif")
' BUT WHY NOT THIS?
' cellImage.Value = Properties.Resources.ResourceManager.GetObject("ExistingRessource")
' OR THIS?
' cellImage.Value = CType(Properties.Resources.ResourceManager.GetObject("ExistingRessource"), Image)
cellImage.ImageLayout = DataGridViewImageCellLayout.Zoom
DataGridView1.Rows(intI).Cells(1) = cellImage
Next
It's working fine if I use "fromFile" with the path to the image and the 2nd column shows the gif picture inside the cell.
Unfortunately, my attempt to load an image from the ressource ("GetObject") fails, and the cell shows a page-symbol with a red cross on it.
I got all the images I need inside the ressource.
How can I achieve this?
Thanks in advance.

If you've added an image to the resources, then you can access it with my.resources.ResourceName where ResourceName seems to be "ExistingRessource" in your case
It's possible that your current attempts are failing because the resource isn't actually added properly, or you have got the spelling wrong on the name? Either way if you use my.resources you can see for certain that the resource is added properly.
cellImage.Value = My.Resources.ExistingRessource

Related

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

How to save data to text file and retrieve

I'm using VB.NET. I am able to load the pics from a folder into a flowlayoutpanel. And then load the clicked picture into a separate picturebox and display the picture's filepath in a label.
Now I want to be able to add rating and description to each of the image in the flowlayoutpanel and save it to a text file in the folder from which the pictures have been loaded. The app should load be able to load the rating and description on the next launch or when the selected image is changed. How do I accomplish this?
You should probably look at accessing the metadata of the pic. This way the info you want is carried with the pic. This is contained in the PropertyItems Class, which is a property of the Image class
Here's a link to an answered question about adding a comment to a jpg. Hope this helps.
Here's an untested conversion of that code in VB.net. You'll probably have to add a reference or 2 and import a couple of namespaces, but syntactically this is correct as near as I can tell.
Public Function SetImageComment(input As Image, comment As String) As Image
Using memStream As New IO.MemoryStream()
input.Save(memStream, Imaging.ImageFormat.Jpeg)
memStream.Position = 0
Dim decoder As New JpegBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad)
Dim metadata As BitmapMetadata
If decoder.Metadata Is Nothing Then
metadata = New BitmapMetadata("jpg")
Else
metadata = decoder.Metadata
End If
metadata.Comment = comment
Dim bitmapFrame = decoder.Frames(0)
Dim encoder As BitmapEncoder = New JpegBitmapEncoder()
encoder.Frames.Add(bitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts))
Dim imageStream As New IO.MemoryStream
encoder.Save(imageStream)
imageStream.Position = 0
input.Dispose()
input = Nothing
Return Image.FromStream(imageStream)
End Using
End Function

Why don't my Labels show in VB.NET Form

After reading this question, I wrote some code to create a label for each attribute of an xml element.
The problem is that when I run the project, my form only displays the first label. I've checked in the immediate window as well as debug window and all of the labels are loaded to the form, but none of them are displayed. Help?
Here's the code that runs when the form loads.
Dim doc As New XmlDocument()
doc.Load("xmlfile")
Dim ability As XmlNode = doc.GetElementsByTagName("ability").Item(0)
Dim numberofLabels = ability.Attributes.Count
ReDim labels(numberofLabels)
For counter As Integer = 0 To numberofLabels - 1
labels(counter) = New Label
labels(counter).Visible = True
labels(counter).Text = ability.Attributes.Item(counter).Name
labels(counter).Location = New System.Drawing.Point(10, 30 + counter * 10)
Me.Controls.Add(labels(counter))
Next
You should be using some layout manager, to help you with control positioning. Doing it manually is not worth the pain. Try using TableLayoutPanel or FlowLayoutPanel. Both can be docked or anchored to a parent control, so everything behaves very smoothly. Otherwise you are looking to write a lot of positioning/resizing code, and then maintaining it later.
Change the value of 10 in the original code line for a new point to a bigger value such as 40, so that new labels could appear separated visually:
labels(counter).Location = New System.Drawing.Point(10 + counter, 30 + counter * 40)

VB.Net using databindings with a picture box

A row, in a data table, iscalled FirstImage contains a url to an image file on a web server. I am trying to bind the data of this row to the image source of the picture box.
My current code:
For Each row As DataRow In ListData.Rows
Dim ImageDecode = ser.Deserialize(Of PropertyImage())(row("Images"))
row("FirstImage") = "http://rental.joshblease.co.uk/propertyimages/" & ImageDecode(0).Image
'Returns http://rental.joshblease.co.uk/propertyimages/image1.jpg
Next row
TxtListName.DataBindings.Add("Text", ListData, "Name")
TxtListSlug.DataBindings.Add("Text", ListData, "Slug")
TxtListCreated.DataBindings.Add("Text", ListData, "Created")
ImgListItem.DataBindings.Add("Image", ListData, "FirstImage", True)
DataRepeater1.DataSource = ListData
But at the moment, the image is still blank. I have tried entering the location into a hidden textbox and copying the data over, but I can;t figure out how to use the controls in a data repeater.
This was the experimental copy from a hidden text box code:
If Me.DataRepeater1.ItemCount > 0 Then
Dim n As Integer = Me.DataRepeater1.ItemCount
For i As Integer = 1 To n
Me.DataRepeater1.CurrentItemIndex = i - 1
Dim item = Me.DataRepeater1.CurrentItem
item.Controls("ImgListItem").ImageLocation = item.Controls("TxtImageLocation").Text
Next
End If
Simply add Picture Box property ImageLocation
ImgListItem.DataBindings.Add("ImageLocation", ListData, "FirstImage", True)
The databinding for the image expects binary image data and in this case your passing it a string. What we can do is convert the image location into a format the binding can understand. Take a look at this link C# Code Snippet - Download Image from URL. Then once you have the image in memory, you will be able to bind it to your PictureBox.
Also, keep in mind that the simplest way shown in this answer would not work for you since URIs are not supported by the BitMap class.

How to reference controls located on different Tabs (VB.NET)

I have an application written in VB.NET that reads data from a file and displays the data on the screen.
Depending on the data in the file, the program has a TabControl with up to 3 tabs and each tab in turn has a DataGridView for displaying data. For example I have a TabControl that has a tab called "Saturday" and a tab called "Sunday".
The problem I am having is that when I read data from a file, the program displays all the data on the Saturday's tab grid because I am not sure how to reference the Grid on the Sunday tab.
To add the DataGridView I am using the following code:
Grid = New DataGridView
Grid.Dock = DockStyle.Fill
Grid.Name = "Grid" & TabControl.SelectedIndex
Grid.Tag = "Grid" & TabControl.SelectedIndex
And this is how I am reading the data in:
If reader.GetAttribute("controltype") = "Tab" Then
SelectedTab = reader.Name
End If
If reader.Name = "cell" Then
y = y + 1
Grid.Rows(i).Cells(y).Style.BackColor = Color.FromName(reader.ReadElementString("cell"))
End If
What I almost want to do is something like (pseudocode):
SelectedTab.Grid.Rows(i).Cells(y).Style.BackColor = Color.FromName(reader.ReadElementString("cell"))
However when I use the above code it complains:
'Grid' is not a member of 'String'
I hope you understand the issue. Let me know if you need clarification
Your code is a little unclear. However, it appears to me that the following line:
If reader.GetAttribute("controltype") = "Tab" Then
SelectedTab = reader.Name
End If
is creating at least one problem. It looks like you are attempting to refer to a Tabpage control by the string representation of its name, but unless I missed something, what that line is actually doing is trying to make a tabpage control type("SelectedTab") refer to a string type. If that is the case, then you will want to try this instead:
If reader.GetAttribute("controltype") = "Tab" Then
TabControl1.SelectedTab = TabControl1.TabPages(reader.name)
End If
It is a little hard to tell from the code you have posted, but that might get you headed down the right path.
++++++++++++
UPDATE: It appears from your code that you are naming each DGV control by appending the index of the tab on which it is located to the string "grid." I am going to assume that you are using a class member variable named "SelectedTab" to represent the current tab selected in the control. I will assume that at the top of your class you have done something like this:
'Form-or-class scoped memebr variables:
Private SelectedTab As TabPage
Private SelectedGrid As DataGridView
You should be able to refer to the active grid control using something like this:
Private Sub TabControl1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
' Set SelectedTab member variable to refer to the new selected tab page:
SelectedTab = TabControl1.SelectedTab
' Set the SelectedGrid to refer to the grid control hosted on the selected tab page:
SelectedGrid = TabControl1.SelectedTab.Controls("Grid" & TabControl1.SelectedIndex.ToString())
End Sub
From here, you should be able to use the member variable for SelectedGrid to refer to the grid present on which ever tab page is selected in your tab control.
It is challenging to address your concerns with only fragments of your code. If you have additional difficulties, please post more of your code, so we can better see what else is going on.
Hope that helps!
Okay, I would go about something like this. Maybe you can simply use a DataSet to load the XML data in one line (if they have been saved with DataSet.WriteXML before).
Dim ds As New DataSet
Dim p As TabPage
Dim gv As DataGridView
ds.ReadXml("F:\testdata.xml")
For i As Integer = TabControl1.TabPages.Count - 1 To 0 Step -1
TabControl1.TabPages.RemoveAt(i)
Next
For Each dt As DataTable In ds.Tables
p = New TabPage(dt.TableName)
gv = New DataGridView
' ... configure the gv here...
gv.AutoGenerateColumns = True
gv.Dock = DockStyle.Fill
' ...
gv.DataSource = dt
TabControl1.TabPages.Add(p)
p.Controls.Add(gv)
Next