VB.Net using databindings with a picture box - vb.net

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.

Related

Check if data exist in file

I need help. I want to check if user exists by entering their ic number and I want to display another rest of their data by using file in visual basic. Unfortunately, an error occurs while doing that. I need help. If the user exists, then It will display automatically name, email, address and so on but if a user doesn't exist, then it shows message box. Here I attached the image of the display screen and the code. Please help me. Thank you.
Public Class Form1
Private Sub btnSearch_Click(sender As Object, e As EventArgs) Handles btnSearch.Click
Dim userFile As String = "C:\Users\HP\Desktop\userdata.txt"
Dim inputFile As String
If System.IO.File.Exists(userFile) = True Then
Dim objReader As New System.IO.StreamReader(userFile)
Dim intIc As Integer
Dim intCount As Integer = 0
Dim strName As String
Dim strEmail As String
Dim intPhoneNum As String
Dim strAdd1 As String
Dim strAdd2 As String
Dim intPostcode As String
Dim strState As String
Do While objReader.Peek() <> -1
intIc(intCount) = Convert.ToInt64(objReader.ReadLine())
If (intIc(intCount).Convert.ToInt64(objReader.ReadLine())) Then
strName(intCount) = objReader.ReadLine()
strEmail(intCount) = objReader.ReadLine()
intPhoneNum(intCount) = Convert.ToInt32(objReader.ReadLine())
strAdd1(intCount) = objReader.ReadLine()
strAdd2(intCount) = objReader.ReadLine()
intPostcode(intCount) = Convert.ToInt32(objReader.ReadLine())
strState(intCount) = objReader.ReadLine()
lblName.Text = strName
lblEmail.Text = strEmail
lblNum.Text = intPhoneNum
lblAdd1.Text = strAdd1
lblAdd2.Text = strAdd2
lblPostcode.Text = intPostcode
lblState.Text = strState
objReader.Close()
Else
MessageBox.Show("User Does Not Exist")
End If
intCount = intCount + 1
Loop
Else
MessageBox.Show("File Does Not Exist")
End If
End Sub
End Class
Your task, the easy way:
make a new project
add a DataSet to this new project
open the DataSet, in the properties call it something sensible
Right click the surface, add a new datatable, name it Person
Right click the datatable, add a column, name it IC. Right click, add column, name it Name. Keep going until you added all the fields you want to track(email,phone,address1 etc)
save the DataSet
open the form
show the datasources window (view menu.. other windows)
expand the nodes til you can see Person
click the drop down next to Person, switch from DataGridview to Details
drag Person onto the form. Text boxes, labels etc appear. In the tray at the bottom more things appear
add a textbox to the form and call it searchTextBox
add a search button to the form, double click it, add this line of code to the click handler:
personBindingSource.Filter = '[ic] LIKE '" & searchTextBox.Text & "'"
If personBindingSource.Count = 0 Then MessageBox.Show("No records")
double click the form background to add a form load event handler, put this line of code:
If IO.File.Exists("data.xml") Then .ReadXml("data.xml")
switch back to designer, single click the form background and switch to event properties of the form, add a handler to the form closing event:
.WriteXml("data.xml")
That's it, you now have a program that will open, read and fill the DataSet with data from the data.xml file, it will search it when you type something in the ic box, the text boxes use databinding to show values automatically, and when you close the program it will save updates data. The only task now is to load the xml file with data.
When the textboxes were added to the form you should also have seen a bar appear across the top with some left/right controls in and a green plus. Click the green plus, type some data in, click it again, type more data. Navigating back, if you're adding new data, will commit the data. If you're looking at existing data, editing it then navigating will commit it
After you added some data, you can search for existing data using the search box. When you've searched for a single value it should be the only thing shown and the nav will show "1 of 1". To get back to the mode where all data is showing, put a single asterisk in the search box and hit search; it should show the number records in the top bar and you can scroll them with the arrows.
If you already have lots of data in a file, like you use in your question, you can read it in a loop (like you do in your question, except don't use that code exactly cos it has loads of errors) as a one time thing and assign it into the datatable, or you can manipulate it directly into being XML in a text editor. This is easy to do if you have a capable text editor but I'll not offer any particular advice on it in case you don't have a large amount of existing data. Ask a new question if you do

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

VB.NET: DataGridViewImageCell - Image from Ressource?

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

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

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