if the file not exits then return no error vb - vb.net

I have start this application every things its work fine but i have a small bug but i can not find the solution to solve the error.
i have debug it and the error its because the file not exist
is there any way to me to populate my datagridview with all *.gif images From a directory and the check if its null or some thing like that.
What i mean is is there any way to my to populate all gif images found on the chose Directory?
in fact i have all ready try like this but i get one error "Provided column already belongs to the DataGridView control.
Well finaly i have found a solution to load all images from a directory to a datagridview programmatic
Here Is The Working Code
Public Class Form5
Private Sub addBtn_Click(sender As Object, e As EventArgs) Handles addBtn.Click
'Populate()
ShowImages()
End Sub
'CLEAR DATAGRIDVIEW
Private Sub clearBtn_Click(sender As Object, e As EventArgs) Handles clearBtn.Click
DataGridView1.Rows.Clear()
End Sub
'WHEN AN IMAGE IS CLICKED
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
MessageBox.Show("You Clicked Image At Col: " + e.ColumnIndex.ToString() + " Row: " + e.RowIndex.ToString())
End Sub
Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Public Sub ShowImages()
Dim directory As New System.IO.DirectoryInfo("C:\avitogifconverter\")
If directory.Exists Then
Dim pngFiles() As System.IO.FileInfo = directory.GetFiles("*.gif")
For Each pngFile As System.IO.FileInfo In pngFiles
If pngFile.Exists Then
Dim image = System.Drawing.Image.FromFile(pngFile.FullName)
Using image
Dim count = 1
' do something with the image like show in picture box
'CONSTRUCT IMG COLUMN
Dim imgCol As DataGridViewImageColumn = New DataGridViewImageColumn()
imgCol.HeaderText = "Photo"
imgCol.Name = "Col 1"
DataGridView1.Columns.Add(imgCol)
'CONSTRUCT ROWS
'FIRST ROW
Dim img As Image = System.Drawing.Image.FromFile(pngFile.FullName)
Dim row As Object() = New Object() {img, img, img}
DataGridView1.Rows.Add(row)
End Using
End If
Next
End If
End Sub
End Class

Using Directory.EnumerateFiles, you could do something like this:
Dim row = New List(Of Image)(3)
For Each filename In Directory.EnumerateFiles("C:\avitogifconverter", "*.gif")
row.Add(Image.FromFile(filename))
If row.Count = 3 Then
DataGridView1.Rows.Add(row.ToArray())
row.Clear()
End If
Next
If row.Count > 0 Then
DataGridView1.Rows.Add(row.ToArray())
row.Clear()
End If

Related

Loop through each item in Listbox and load a webpage

I'm trying to load a new webpage through the control webview2 in .net6+ windows forms, and I'm using a listbox to extract any single item and add it to the url to load on webview.
For example in listbox I have:
11
22
33
44
55
I would like at the press of a button that a loop starts to load one by one,each of these items like
WebView21.Source = New Uri("https://google.it" & ListBox1.Items.first & "rest of the url")
and after the webpage is loaded, it s supposed to extract it's html to check if a certain string is present with
Dim html As String
html = Await WebView21.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
MsgBox("In Vacanza")
Else
MsgBox("Attivo")
End If
End Sub
after that, it goes back to the second listbox item, load the webview, check the html and so on.
My question is how can I loop the WebView in order to pick each of the items one by one and to proceed to do these little things in the while?
p.s. Once the loop arrives to the last listbox item, would it be possible to start it again from the first item?
Much thanks
edit1:
I'm trying with
Private ReadOnly resetEvent As New ManualResetEvent(False)
Async Sub scanWeb()
For Each listBoxElem As String In ListBox1.Items
resetEvent.Reset()
AddHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
WebView2.Source = New Uri("https://ikalogs.ru/tools/map/?page=1&server=22&world=10&state=active&search=city&allies%5B1%5D=&allies%5B2%5D=&allies%5B3%5D=&allies%5B4%5D=&nick=" & listBoxElem & "&ally=&island=&city=&x=&y=")
Await Task.Run(Sub() resetEvent.WaitOne())
RemoveHandler WebView2.CoreWebView2.NavigationCompleted, AddressOf OnNavigationCompleted
Dim html As String
html = Await WebView2.ExecuteScriptAsync("document.documentElement.outerHTML;")
If html.Contains("Not found") Then
DataGridView1.Rows.Add(listBoxElem, "IN vacanza")
Else
DataGridView1.Rows.Add(listBoxElem, "Attivo")
End If
Next
End Sub
Private Sub OnNavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
resetEvent.Set()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebView2 = New WebView2()
WebView2.EnsureCoreWebView2Async()
End Sub
but it seems the loop doesn't wait for the process to end and it goes straight to the next listbox item...
best way is to enumerate listBox items in a for-each loop : (I added an escape way -simple mouse clic on form - to quit loop)
Dim wStop As Boolean
sub scanWeb()
Do
For Each listBoxElem As String In ListBox1.Items
WebView21.Source = New Uri("https://google.it" & listBoxElem & "rest of the url")
'etc....
Next
Loop Until wStop = True
wStop = False
end sub
'way to stop scan
Private Sub form_clic(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick
wStop = True
End Sub
*** Update *****
The webview2 control is rather made to display data, and I have no experience on it.
Also I suggest you use a simpler method, based on System.Net.WebClient() and associated with threading.
Here is a start of code that works:
Dim wStop As Boolean
Dim i As Integer = 0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim BackProcess = New Thread(Sub() Me.scanWeb())
BackProcess.Priority = ThreadPriority.Normal
BackProcess.Start()
end sub
Sub scanWeb()
Do While Not wStop
Dim WC As New System.Net.WebClient()
'change url for your need
Dim url As String = "https://www.google.fr/search?q=" & ListBox1.Items(i)
Dim s As System.IO.Stream = WC.OpenRead(url)
Dim sr As New System.IO.StreamReader(s)
Dim html As String = sr.ReadToEnd()
If html.Contains("Not found") Then 'beginInvoke allows the back task to communicate with UI
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "In vacanza"))
Else
Me.BeginInvoke(Sub() DataGridView1.Rows.Add(ListBox1.Items(i), "Attivo"))
End If
i += 1
If i > ListBox1.Items.Count - 1 Then i = 0
Loop
End Sub
'button event to stop scanning
Private Sub stopScan_Click(sender As Object, e As EventArgs) Handles stopScan.Click
wStop = True
End Sub

System.NullReferenceException with datagridview

I'm trying to fill two arrays with the content of two columns of a Datagridview. I wrote this:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim t As Integer = (DataGridView1.Rows.Count - 1)
For i = 0 To t
avx(i) = DataGridView1.Rows(i).Cells("Av").Value
hi(i) = DataGridView1.Rows(i).Cells("h").Value
avsum = Val(avsum + avx(i))
Next
Label2.Text = Val(avsum)
End Sub
When I start debugging, I receive this error at the fourth line of the reported code.
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Does someone know how to solve this issue? How could I initialise Datagridview1? It has been already initialised in Designer section so, if I try to initialise it again, I receive obviously a conflict.
Based on my test, I can not reproduce your problem.
However, I make a sample code that may be similar to your question.
Form_Load event
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim table As New DataTable
table = New DataTable()
table.Columns.Add("Av")
table.Columns.Add("h")
table.Rows.Add("test1", "1001")
table.Rows.Add("test2", "1002")
table.Rows.Add("test3", "1003")
DataGridView1.DataSource = table
DataGridView1.AllowUserToAddRows = False
End Sub
Note: The AllowUserToAddRows property will reduce an extra row.
Button_Click event:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim t As Integer = (DataGridView1.Rows.Count - 1)
Dim array1(t) As String
Dim array2(t) As String
For i = 0 To t
array1(i) = DataGridView1.Rows(i).Cells("Av").Value
array2(i) = DataGridView1.Rows(i).Cells("h").Value
Next
For index = 0 To t
RichTextBox1.AppendText(array1(index) + Environment.NewLine)
RichTextBox2.AppendText(array2(index) + Environment.NewLine)
Next
End Sub
Final result:
Can you describe about variable avx() and hi()
This error occur maybe datagridview row count greater than Array bound

How do I make my button save results?

I've been playing around learning the ropes of VB.NET. I have started making my own small generator which just generates txt on the left hand side listbox based on whatever the user chooses in the combo box as you can see in the picture. I would like to configure the already Save Results to open a file dialog box and allow the user to say what is already in the listbox in a txt file in any directory he or she choose. Please look at my VB Program picture below to get a better understanding
My VB program
Imports System.IO
Public Class Form1
Private Sub Button11_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.Value = ProgressBar1.Value + 60 'change this to incrase green bar'
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' declare the required variables
Dim i As Integer = 0
Dim item As String
Dim fileReader As StreamReader
' set the value min and max values of progress bar
' clear the contents of the ListBox1
ListBox1.Items.Clear()
' check whether an item is selected in the combox1
If ComboBox1.SelectedIndex <> -1 Then
' is selected get the item
item = ComboBox1.SelectedItem.ToString()
Else
' otherwise set item to empty
item = ""
End If
' depending on the item initialize the fileReader with
' with respective file name
If item.Equals("Random") Then
fileReader = New StreamReader("world mix.txt")
ElseIf item.Equals("China") Then
fileReader = New StreamReader("china.txt")
ElseIf item.Equals("Korea") Then
fileReader = New StreamReader("korea.txt")
ElseIf item.Equals("United Arab Emirates") Then
fileReader = New StreamReader("ae.txt")
ElseIf item.Equals("Russia") Then
fileReader = New StreamReader("ru.txt")
ElseIf item.Equals("USA") Then
fileReader = New StreamReader("usa lead.txt")
ElseIf item.Equals("New Zeland") Then
fileReader = New StreamReader("nz.txt")
Else
fileReader = New StreamReader("names.txt")
End If
' loop till end of the file
Do While fileReader.Peek() <> -1
' check whether the progress is less than 200
' if so just increment the progress bar value
If ProgressBar1.Value <= 100 Then
' set the line that is read into the listBox
ListBox1.Items.Add(fileReader.ReadLine().ToString())
' increment the iterator
End If
Loop
' close the file
fileReader.Close()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' when stop button is clicked, just display a pop up message
MessageBox.Show("The progress bar has stopped!")
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
''This is the save results button button''
End Sub
End Class

For Loop works not working, or giving error. Works when conditions are reversed

I don't know if its the late hour, but I am working on the following array For Loop:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pboxes() As PictureBox = {picMainImage, picImage2, picImage3, picImage4}
For i As Integer = 0 To pboxes.Count - 1
If pboxes(i).Image Is My.Resources.list Then
pboxes(i).Image = Nothing
End If
Next
End Sub
The loop is supposed to check if any of the picture boxes in the array have an Image called List stored on the Resources folder in them. If it does, set the image to Nothing. However, I run it and nothing happens., no errors, nothing.
So I reversed my For Loop as follows to see what happens:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pboxes() As PictureBox = {picMainImage, picImage2, picImage3, picImage4}
For i As Integer = 0 To pboxes.Count - 1
If pboxes(i).Image Is Nothing Then
pboxes(i).Image = My.Resources.list
End If
Next
End Sub
This works but is not what I want, I want the opposite.
What am I doing wrong here?
One option is if you set the pictures in the box programatically, set My.Resources.list to be referenced by a global variable, ie Public pbList = My.Resources.list
Then, when you set the picture initially, use that variable, so: picMainImage.Image = pbList
Finally, in your If statement, you should then be able to check If pboxes(i) is pbList Then...
Once it becomes a variable, it seems to become static and therefore wherever you use it, it will always be the same.
EDIT: some actual code that I used a few months back:
In the module (outside sub)
Public pbimage As System.Drawing.Image = My.Resources.placeholder
Then in the Sub
If imgpath <> "" Then
Me.lblImg.ImageLocation = imgpath
Else
Me.lblImg.ImageLocation = Nothing
Me.lblImg.Image = pbimage
End If
and then this is what I use for all pictures without issues (its a function that I have run when you click on an image - if its the placeholder then you can browse for an image and save it to a data folder, otherwise it does nothing)
Private Sub changeImg(sender As Object, e As MouseEventArgs) Handles {ALL YOUR IMAGES}.Click
If TypeOf sender Is PictureBox Then
If DirectCast(sender, PictureBox).Image Is pbimage Then
Dim ofd As New OpenFileDialog
ofd.Title = "Please select image"
ofd.Filter = "Image Files|*.jpg"
If ofd.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim rn As New Random
Dim r As Long = rn.Next(111111, 999999)
Dim newfilename As String = My.Settings.dataPath & r.ToString & Format(Now, "ddmmyy") & ".jpg"
Try
FileCopy(ofd.FileName, newfilename)
DirectCast(sender, PictureBox).ImageLocation = newfilename
Catch ex As Exception
MessageBox.Show("Check permissions to the Data folder", "Permissions error")
End Try
End If
End If
End If
End Sub
Images cannot be compared that way because the image is copied into memory and will always be different even if the pixels match. Compare the pixels directly to find out if the image is the same.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pboxes() As PictureBox = {picMainImage, picImage2, picImage3, picImage4}
For i As Integer = 0 To pboxes.Count - 1
If IsSameImage(pboxes(i).Image, My.Resources.list) = True Then
pboxes(i).Image = Nothing
End If
Next
End Sub
Public Function IsSameImage(ByVal oBitmap1 As Bitmap, ByVal oBitmap2 As Bitmap) As Boolean
For x = 0 To oBitmap1.Width - 1
For y = 0 To oBitmap2.Height - 1
If Not oBitmap1.GetPixel(x, y) = oBitmap2.GetPixel(x, y) Then
Return False
End If
Next
Next
Return True
End Function

How to save data within the Application?

I'm creating a basic To-do program. I want to save the list of tasks the user creates. Now I've tried with saving them as text files but I don't want it that way. I want it so that I can save the tasks the user creates within the program rather than external text files and then retrieve those saved files and display them in a text file.
Essentially I need a way to save data without needing to rely on databases.
A good example is GeeTeeDee. It seems to be saving its files and data etc. in the program within rather than external text file.(I'm assuming this because I can't seem find them. I could be wrong)
Update
I was doing a bit of searching can came across this: Click here!!!
But the problem is that I'm confused as to how this works. Is someone able to clear things for me? It would be GREATLY appreciated as it's exactly what I'm looking for.
The "code project" example saves the data at an external file with extension [*.brd] .
You can Use XmlSerializer to save and load your data from external xml file with extension xml,brd or anything else.
Try the code below, add into a form1 three buttons (Button1,Button2,Button3) and a DataGridView1, paste the code and Run.
press button "add data dynamically" or/and add,edit,delete row directlly from DataGridView1.
press Save data.
close and run programm
press Load data.
Imports System.Xml.Serialization
Imports System.IO
Class Form1
Dim ds As DataSet
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Button1.Text = "Load Data"
Button2.Text = "add data dynamically"
Button3.Text = "Save Data"
'Create Dataset
ds = CreateDataset()
'Set DataGridView1
DataGridView1.DataSource = ds.Tables("Person")
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
LoadFromXMLfile("c:\temp\persons.xml")
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
AddDataToDataSetDynamically(ds)
End Sub
Private Sub Button3_Click_1(sender As System.Object, e As System.EventArgs) Handles Button3.Click
SaveToXMLFile("c:\temp\persons.xml", ds)
End Sub
Private Function CreateDataset() As DataSet
Dim dataset1 As New DataSet("Persons")
Dim table1 As New DataTable("Person")
table1.Columns.Add("Id")
table1.Columns.Add("FName")
table1.Columns.Add("Age")
'...
dataset1.Tables.Add(table1)
Return dataset1
End Function
Private Sub AddDataToDataSetDynamically(d As DataSet)
d.Tables("Person").Rows.Add(1, "Andrew", "46")
d.Tables("Person").Rows.Add(2, "Nicky", "43")
d.Tables("Person").Rows.Add(3, "Helen", "15")
End Sub
Private Sub SaveToXMLFile(filename As String, d As DataSet)
Dim ser As XmlSerializer = New XmlSerializer(GetType(DataSet))
Dim writer As TextWriter = New StreamWriter(filename)
ser.Serialize(writer, d)
writer.Close()
End Sub
Private Sub LoadFromXMLfile(filename As String)
If System.IO.File.Exists(filename) Then
Dim xmlSerializer As XmlSerializer = New XmlSerializer(ds.GetType)
Dim readStream As FileStream = New FileStream(filename, FileMode.Open)
ds = CType(xmlSerializer.Deserialize(readStream), DataSet)
readStream.Close()
DataGridView1.DataSource = ds.Tables("Person")
Else
MsgBox("file not found! add data and press save button first.", MsgBoxStyle.Exclamation, "")
End If
End Sub
End Class
add that code to form1 and get the data to a textbox (add button4,textbox1)
Private Function PrintRows(dataSet As DataSet) As String
Dim s As String = ""
Dim thisTable As DataTable
For Each thisTable In dataSet.Tables
Dim row As DataRow
For Each row In thisTable.Rows
Dim column As DataColumn
For Each column In thisTable.Columns
s &= row(column) & " "
Next column
s &= vbCrLf
Next row
Next thisTable
Return s
End Function
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
TextBox1.Text = PrintRows(ds)
End Sub