System.NullReferenceException with datagridview - vb.net

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

Related

VB.NET: How to copy selected cell data to the first selected cell in other form?

My question may be confusing but here is the step by step process of the output I want to accomplish.
first when I click a cell in the fist form, another form pop's up. see images..
Image 1 Image 2
then if I click the cell data of the second form it should copy the selected row data of Code and Short Name to the first datagridview cell in form 1
Here is my code so far:
Private Sub SearchJournalGrid_CellContentDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles SearchJournalGrid.CellContentDoubleClick
With GeneralJournal
.GridJournal.Rows(.GridJournal.SelectedRows(0).Index).Cells("Code").Value = SearchJournalGrid.Rows(SearchJournalGrid.SelectedRows(0).Index).Cells("CODE").Value.ToString
.GridJournal.Rows(.GridJournal.SelectedRows(0).Index).Cells("Account Name").Value = SearchJournalGrid.Rows(SearchJournalGrid.SelectedRows(0).Index).Cells("Short Name").Value.ToString
End With
End Sub
Let me know if I got it right!
Start a new project with only two forms in it, Form1 & Form2, add a DataGridView in each with their original name, which will DataGridView1 by default.
I have created 3 columns for each of them.
The code which has placed on the only Form1 is in the following:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To 5
DataGridView1.Rows.Add(New String() {i + 1, "ITEM " & i + 1, "Description " & i + 1})
Next
End Sub
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim ROW_ID As Integer = DataGridView1.CurrentCell.RowIndex
Dim DGV_Row As DataGridViewRow = DataGridView1.Rows(ROW_ID).Clone
For J As Integer = 0 To DGV_Row.Cells.Count - 1
DGV_Row.Cells(J).Value = DataGridView1.Rows(ROW_ID).Cells(J).Value
Next
With Form2
.DataGridView1.Rows.Clear()
.DataGridView1.Rows.Add(DGV_Row)
End With
Form2.Show()
End Sub

Creating handle in a Windows Form with a declared object as an array

Im trying to make a Connect 4 game just to practice some windows forms which im new to. What my code does is creates a grid of 7 x 6 regularly spaces blank PictureBox's. But since im creating them in the script and not using the form1 design windows i dont know how i would add Handles to them, especially since the PictureBox's are in an array. Any ideas?
Public Class Form1
Dim Grid(6, 5) As PictureBox
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Button1.Visible = False
Me.FormBorderStyle = FormBorderStyle.FixedSingle
For i As Integer = 0 To 6
For j As Integer = 0 To 5
Grid(i, j) = New PictureBox
Grid(i, j).BackColor = Color.LightGray
Grid(i, j).Size = New Size(90, 90)
Grid(i, j).Location = New Point((i * 100) + 10, (j * 100) + 10)
Grid(i, j).Visible = True
Controls.Add(Grid(i, j))
Next
Next
End Sub
Private Sub Grid_MouseHover(sender As Object, e As EventArgs) Handles Grid(x, y).MouseHover 'Doesnt work
'Run depending on which picturebox in array
End Sub
End Class
I can get an error which is "Handles clause requires a WithEvents variable defined in the containing type or one of its base types."
One possible way would be to set the .Tag property using the coordinates -
add something like into your For..Next loop
Grid(i, j).Tag = i.ToString & j.ToString
and use
AddHandler Grid(i, j).MouseHover, AddressOf Grid_MouseHover
and add this after the one above.
Then, change the first line of your MouseHover Sub to
Private Sub Grid_MouseHover(sender As Object, e As EventArgs)
with no handler on the end.
Finally, change the type of the sender to a PictureBox
Private Sub Grid_MouseHover(sender As Object, e As EventArgs)
Dim Pbox As PictureBox = CType(sender, PictureBox)
Dim i As Integer = Integer.Parse(Pbox.Tag.ToString(0))
Dim j As Integer = Integer.Parse(Pbox.Tag.ToString(1))
End Sub
To access the Picturebox and its properties, just use PBox and if you need the coordinates, use i and j

vb.net How to overwrite the text in a combobox after the dropdownclosed event

I created this piece of code to illustrate the idea, it uses a combobox and a textbox
Private Sub ComboBox2_DropDown(sender As Object, e As EventArgs) Handles ComboBox2.DropDown
ComboBox2.Items.Clear()
ComboBox2.Items.Add("0001 | Apple")
ComboBox2.Items.Add("0002 | Pear")
ComboBox2.Items.Add("0003 | Banana")
ComboBox2.Items.Add("0004 | Pineapple")
ComboBox2.Items.Add("0005 | Cherry")
End Sub
Private Sub ComboBox2_DropDownClosed(sender As Object, e As EventArgs) Handles ComboBox2.DropDownClosed
Dim selecteditem As String = ComboBox2.Items(ComboBox2.SelectedIndex)
ComboBox2.Text = Strings.Left(selecteditem,4)
TextBox2.Text = Strings.Left(selecteditem,4)
End Sub
When I select an item from the combobox what happens is that the combobox keeps showing the whole string while the textbox only shows the first 4 characters.
How can I overwrite the combobox text after I close the combobox?
* edit *
I tried a combo of the solutions but ran into a problem because the data was bound to a datasource so it's not possible to change the item.
This is the new code:
Private Sub ComboBox2_DropDown(sender As Object, e As EventArgs) Handles ComboBox2.DropDown
SQL.ExecQuery($"select ID, Name, RTRIM(ID + ' | ' + Name) as SingleColumn from GCCTEST.dbo.tblFruit")
ComboBox2.DataSource = SQL.DBDT
ComboBox2.DisplayMember = "SingleColumn"
End Sub
Private Sub ComboBox2_DropDownClosed(sender As Object, e As EventArgs) Handles ComboBox2.DropDownClosed
ComboBox2.DisplayMember = "ID"
ComboBox2.SelectedIndex = 0
End Sub
Now I only need to have the 0 be the index I chose...
The following should work.
If not necessary, don't populate the combobox on every drop-down, instead call the FillComboBox-method when loading the Form.
Private Sub FillComboBox()
SQL.ExecQuery($"select ID, Name, RTRIM(ID + ' | ' + Name) as SingleColumn from GCCTEST.dbo.tblFruit")
ComboBox2.DataSource = SQL.DBDT
ComboBox2.DisplayMember = "ID"
ComboBox2.ValueMember = "ID"
End Sub
Private Sub ComboBox2_DropDown(sender As Object, e As EventArgs) Handles ComboBox2.DropDown
Me.ComboBox2.DisplayMember = "SingleColumn"
End Sub
Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
Dim selV As Object = Me.ComboBox2.SelectedValue
Me.TextBox2.Text = CStr(selV)
Me.ComboBox2.DisplayMember = "ID"
'Set the current value again, otherwise the combobox will always display the first item
Me.ComboBox2.SelectedValue = selV
End Sub
I used a few properties and .net String.SubString method instead of the old vb6 Strings.Left.
Private Sub ComboBox1_DropDownClosed(sender As Object, e As EventArgs) Handles ComboBox1.DropDownClosed
Dim SelectedString As String = ComboBox1.SelectedItem.ToString
Dim ChangedString As String = SelectedString.Substring(0, 4)
Dim index As Integer = ComboBox1.SelectedIndex
ComboBox1.Items(index) = ChangedString
End Sub
You can fill your combo box one by one to avoid binding problems as follows...
Private Sub ComboBox1_DropDown(sender As Object, e As EventArgs) Handles ComboBox1.DropDown
Using cn As New SqlConnection("Your connection string")
Using cmd As New SqlCommand("Select ID, Name From tblFruit;", cn)
cn.Open()
Using dr As SqlDataReader = cmd.ExecuteReader
ComboBox1.BeginUpdate()
While dr.Read
ComboBox1.Items.Add(dr(0).ToString & " | " & dr(1).ToString)
End While
ComboBox1.EndUpdate()
End Using
End Using
End Using
You can solve this graphical problem putting a Label in your Form and moving it over your ComboBox.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.Label1.AutoSize = False
Me.Label1.BackColor = Me.ComboBox1.BackColor
Me.Label1.Location = New Point(Me.ComboBox1.Location.X + 1, Me.ComboBox1.Location.Y + 1)
Me.Label1.Size = New Size(Me.ComboBox1.Width - 18, Me.ComboBox1.Height - 2)
Me.ComboBox1.Items.Add("0001 | Apple")
Me.ComboBox1.Items.Add("0002 | Pear")
Me.ComboBox1.Items.Add("0003 | Banana")
Me.ComboBox1.Items.Add("0004 | Pineapple")
Me.ComboBox1.Items.Add("0005 | Cherry")
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Me.Label1.Text = Trim(Me.ComboBox1.SelectedItem.Split("|")(0))
End Sub
Please note that:
you can populate your ComboBox a single time during Form load event
you can use SelectedIndexChanged instead of DropDown and DropDownClosed event
if this is not a graphical problem please give a look at DisplayMember and ValueMember properties

if the file not exits then return no error vb

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

Pass variable to new form with Datatable and Listbox

I am currently trying to write an application like address book. Listbox works properly, it shows everything corretly. But I need to pass id of chosen listbox item to another form. I got code like this in Form2:
Private myTable As New DataTable()
Public Sub LoadXml(sender As Object, e As EventArgs) Handles Me.Load
With myTable.Columns
.Add("DisplayValue", GetType(String))
.Add("HiddenValue", GetType(Integer))
End With
myTable.DefaultView.Sort = "DisplayValue ASC"
ListBox1.DisplayMember = "DisplayValue"
ListBox1.ValueMember = "HiddenValue"
ListBox1.DataSource = myTable
Dim doc As New Xml.XmlDocument
doc.Load("c:\address.xml")
Dim xmlName As Xml.XmlNodeList = doc.GetElementsByTagName("name")
Dim xmlSurname As Xml.XmlNodeList = doc.GetElementsByTagName("surname")
Dim xmlId As Xml.XmlNodeList = doc.GetElementsByTagName("id")
For i As Integer = 0 To xmlName.Count - 1
Dim nazwa As String = xmlName(i).FirstChild.Value + " " + xmlSurname(i).FirstChild.Value
myTable.Rows.Add(nazwa, xmlId(i).FirstChild.Value)
MsgBox(myTable.Rows(i).Item(1).ToString)
Next i
ListBox1.Sorted = True
End Sub
Later in the code I have event:
Public Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick
End Sub
I would like to know how can I call id from DataTable for selected listbox item. I hope u understand what I mean since my english is not perfect :)
Since you have added the XML value id to the data table column HiddenValue and you have assigned HiddenValue as the ValueMember for the listbox, once a record is selected in the listbox, id will be available in the listbox's [SelectedValue][1] member. For example:
Public Sub ListBox1_DoubleClick(sender As Object, e As EventArgs) Handles ListBox1.DoubleClick
MsgBox("Selected Id: " & ListBox1.SelectedValue.ToString())
End Sub