Bind a Class Property that returns a list to a DataGridViewComboBoxColumn - vb.net

I have a file name that is found at multiple paths. I want to present this data to the user in the format of a DGV. I have a DGV with one text box column for the name, and another combobox column for the paths. I am having trouble getting the combobox column to bind to the property of the class that returns the paths.
Any help would be much appreciated.
Public Class fileTest
Public Property FileName As String
Public Property Paths As String()
Public Sub New(ByRef _name As String, ByVal _paths As String())
Me.FileName = _name
Me.Paths = _paths
End Sub
End Class
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim fileList As New BindingList(Of fileTest)
fileList.Add(New fileTest("TEST", {"ABC", "123"}))
Me.DataGridView1.AutoGenerateColumns = False
Me.DataGridView1.DataSource = fileList
Me.DataGridView1.Columns("FileName").DataPropertyName = "FileName"
CType(Me.DataGridView1.Columns("Paths"), DataGridViewComboBoxColumn).DataPropertyName = "Path"
End Sub

DataGridViewComboBoxColumn is horrible. HORRIBLE.
We eventually gave up using it and now just float a standard Combobox over the grid.

Related

How to save many object (with the same class) to txt file and binding those object with listbox VB.NET

I try to program a simple project to save data to txt file, read it and use binding data to show it. My project like this.
When I add ID Person to "Add ID" textbox (Textbox which near Button "Add ID"). It will add ID to Listbox and "ID Name" textbox. With this IDName, I insert FirstName and LastName for first person and Save Person's Name. Then, I Add new ID in "Add ID" textbox and fill First,last name and save it again
I refer this page http://vbnetsample.blogspot.de/2007/12/serialize-deserialize-class-to-file.html?m=1 to save and read data to txt file. It's run ok. But my problem is that when I save Person 2 with ID 2, Person 1 is overwrited. I think I can save Person to List Person. But it will make difficult when I want to update any Person's data. I don't know whether Is there any way to save and update each person. And by the way How can I show data by binding data in listbox.
Here is my code
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO
Public Class Form1
Public pPerson As New Person
'Serialize and Save Data to txt file
Private Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveButton.Click
pPerson.IDName = IDNameTextBox.Text
pPerson.FirstName = FirstNameTextBox.Text
pPerson.LastName = LastNameTextBox.Text
Dim fs As FileStream = New FileStream("C:\Users\Bruce\Desktop\test.txt", FileMode.OpenOrCreate)
Dim bf As New BinaryFormatter()
bf.Serialize(fs, pPerson)
fs.Close()
End Sub
'Deserialize and Read Data from txt file
Private Sub ReadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ReadButton.Click
If FileIO.FileSystem.FileExists("C:\Users\Bruce\Desktop\test.txt") Then
Dim fsRead As New FileStream("C:\Users\Bruce\Desktop\test.txt", FileMode.Open)
Dim bf As New BinaryFormatter()
Dim objTest As Object = bf.Deserialize(fsRead)
fsRead.Close()
IDNameTextBox.Text = objTest.IDName
FirstNameTextBox.Text = objTest.FirstName
LastNameTextBox.Text = objTest.LastName
End If
End Sub
Private Sub AddIDButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddIDButton.Click
ListBox1.Items.Insert(0, AddIDTextBox.Text)
IDNameTextBox.Text = AddIDTextBox.Text
End Sub
End Class
'Create Class Person
<System.Serializable()>
Public Class Person
Private m_sIDName As String
Private m_sFirstName As String
Private m_sLastName As String
Public Sub New()
End Sub
Public Property IDName() As String
Get
Return Me.m_sIDName
End Get
Set(ByVal value As String)
Me.m_sIDName = value
End Set
End Property
Public Property FirstName() As String
Get
Return Me.m_sFirstName
End Get
Set(ByVal value As String)
Me.m_sFirstName = value
End Set
End Property
Public Property LastName() As String
Get
Return Me.m_sLastName
End Get
Set(ByVal value As String)
Me.m_sLastName = value
End Set
End Property
End Class
To me it seems like the issue here is
Dim fs As FileStream = New FileStream("C:\Users\Bruce\Desktop\test.txt", FileMode.OpenOrCreate)
you have to change it to this:
If not File.Exists("C:\Users\Bruce\Desktop\test.txt") Then
File.create("C:\Users\Bruce\Desktop\test.txt")
End If
Dim fs As FileStream = New FileStream("C:\Users\Bruce\Desktop\test.txt", FileMode.Append)
The whole problem was that your file was simply open (or created if it was not there before) and being written from the first line.By using FileMode.Append your File will be opened and anything new will be tried to be written at the end of the file.
Let me know if this worked :)

Add rows to class bound datagridview

Hi I'm trying to bind a list of objects to a datagridview
Binding a existing list(Of is working but I'm trying to add or remove a object from, my dgv isn't updating.
Public Class Form1
Dim lt As New List(Of Test)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lt.Add(New Test("Mac", 2200))
lt.Add(New Test("PC", 1100))
dgv.DataSource = lt
lt.Add(New Test("Android", 3300)) 'This line won't appear in the dgv
End Sub
End Class
Public Class Test
Public Sub New(ByVal name As String, ByVal cost As String)
_name = name
_cost = cost
End Sub
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _cost As String
Public Property Cost() As String
Get
Return _cost
End Get
Set(ByVal value As String)
_cost = value
End Set
End Property
End Class
How can I add or remove or change a value from the dgv to the list and inverse?
NoiseBe
Change this line:
Dim lt As New List(Of Test)
To:
Imports System.ComponentModel
...
Private lt As New BindingList(Of Test)
When the collection contents will change, you should use a BindingList(Of T). This collection has events associated with it which make it aware of changes to the list contents.
If in addition to the list contents, the list items will change (like Test.Name), you should also implement INotifyPropertyChanged on the class itself.
Another way to do it:
dgv.DataSource = Nothing
lt.Add(New Test("Android", 3300))
dgv.DataSource = lt
This "resets" the DataSource so that the new contents will show up. However, it means that several other things get reset like selected items; if you are binding to a List/Combo control, you will also have to reset the ValueMember and DisplayMember properties as well.

How to initialize an object array that was created inside a Structure in VB.NET?

No matter what I do, I end up with Object reference not set to an instance of an object at runtime. The problem is RptParamList().
The Structure is...
Partial Class WebReports_RptGeneric
Inherits Page
Protected ObjUtils As New Utilities
Protected ObjDtn As New DataTable
Structure SchedParms
Shared ReportName As String
Shared RptParamList() As ParameterValue
End Structure
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim objSecurit As New STISecurity
Dim intRc As Integer
Dim objAudit As New Audits
...
Public Sub XqtSaveSched(ByVal sender As System.Object, ByVal e As System.EventArgs)
'Get Report Name and Report Parameters
paramList.Clear()
dt.Reset()
dt = ObjUtils.GetDataTableForQuery("sp_GetPosFieldNames", paramList)
ReDim SchedParms.RptParamList(13)
SchedParms.RptParamList(0).Name = "rpFY" (BLOWS UP HERE!!)
SchedParms.RptParamList(0).Value = CStr(Session("FY"))
SchedParms.RptParamList(1).Name = "rpUserID"
SchedParms.RptParamList(1).Value = "1000000"
SchedParms.RptParamList(2).Name = "rpShowLinks"
SchedParms.RptParamList(2).Value = CStr(False)
I tried adding the ReDim statement as an initializer, but that didn't work. I also tried SchedParms.RptParamList(0) = new ParameterValue() , but that didn't work either.
You need to create an array with the New keyword, otherwise RptParamList will be Nothing
Shared RptParamList As ParameterValue() = New ParameterValue(13) {}
If the array can grow, use a List(Of ParameterValue), rather than redimmming an array. Lists do that automatically.
Shared RptParamList As New List(Of ParameterValue)()
Then add items with the Add method
SchedParms.RptParamList.Add(New ParameterValue())

When ever I change an attribute of a class, the window won't open

When ever I try to change an attribute in the load method of a class I created, it won't let me open it. If I leave the load method blank or put anything else there, it works fine.
Public Class Main
'SHIPS
Dim AirCraftCarrier As Ship
Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AirCraftCarrier.name = "ACC" ' These won't work
AirCraftCarrier.SetAttributes("ACC", AirCraftCarrier_image, 5, "vertical", new_pos, False, False) ' If I leave it blank or keep anything else here, it opens fine.
End Sub
End Class
Public Class Ship
Public name As String
Public image As PictureBox
Public direction As String
Public selection As Boolean
Public placed As Boolean
Public location(2) As Integer
Public Sub SetAttributes(ByVal name1 As String, ByVal image1 As PictureBox, ByVal length1 As Integer, ByVal direction1 As String, ByVal location1 As Array, ByVal selected1 As Boolean, ByVal placed1 As Boolean)
name = name1
image = image1
direction = direction1
selection = selected1
placed = placed1
location(0) = location1(0)
location(1) = location1(1)
End Sub
End Class
First changes to Ship. Classes tend to use Properties rather than fields:
Public Class Ship
Public Property name As String
Public Property image As PictureBox ' bad name; Net has an Image class
' etc
' set essential props via the constructor:
Public Sub New(sName As String, picB As PictureBox)
name = sName
image = picB
End Sub
Then in main for creating it:
Public Class Main
Dim AirCraftCarrier As Ship ' this is just a variable declaration
Private Sub Main_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Load
' Create an instance:
AirCraftCarrier = New Ship("ACC", frm.PicBoxName)
' set other properties
AirCraftCarrier.Direction = "SSW"
AirCraftCarrier.Foo = "Bar"
End Sub
End Class
With a constructor you can pass the essential information, like the unique name to the class when you create it. This is used instead of the SetAttributes sub.

Retrieve a object from a list of objects in visual basic and use it to fill text/combo boxes

I have a class as seen below:
Public Class parameters
Public Property test As String
Public Property test_type As String
Public Property user_test_name As String
Public Property meas As String
Public Property spec As String
...etc
End Class
I make a list of objects that I import from a csv somewhere. The user_test_name's from the list gets sent to a list box:
For Each parameters In param
' MsgBox(parameters.user_test_name)
ListBox1.Items.Add(parameters.user_test_name)
Next
now when the user selects something from the list i want the rest of the properties of that particular user_test_name object to populate in certain text/combo boxes in the application. Here is how I grab what is selected.
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim selected_name As String = ListBox1.SelectedItem()
' MsgBox(selected_name)
find_object_by_user_test_name(selected_name)
End Sub
Now i'm having difficulty finding the object with the selected_name from the list and using its properties to fill the text.combo boxes. I tried the following to no success:
Public Sub find_object_by_user_test_name(ByVal description)
MsgBox(description)
Dim matches = From parameters In param
Where parameters.user_test_name = description
Select parameters
' MsgBox(matches)
' MsgBox(matches.user_test_name)
TextBox1.Text = matches.test
TextBox2.Text = matches.test_name
etc,,, on and on
' populate_area(matches)
End Sub
Instead of adding the name (a string) to the ListBox, add your actual INSTANCE to it.
First, override ToString() in your class so that it displays properly in your ListBox:
Public Class parameters
Public Property test As String
Public Property test_type As String
Public Property user_test_name As String
Public Property meas As String
Public Property spec As String
Public Overrides Function ToString() As String
Return user_test_name
End Function
End Class
Next, add each instance to the ListBox:
For Each parameters In param
ListBox1.Items.Add(parameters)
Next
Now, the SelectedIndexChanged() event, you can cast the SelectedItem() item back to parameters and you already have everything at your disposal:
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
If ListBox1.SelectedIndex <> -1 Then
Dim P As parameters = DirectCast(ListBox1.SelectedItem, parameters)
' ... do something with "P" ...
Debug.Print(P.user_test_name & " --> " & P.test)
End If
End Sub
If the user_test_names are unique, it may be easier to use a dictionary and retrieve the objects that way.
Dim params As New Dictionary(Of String, parameters)
params.add(MyParameterObject.user_test_name, MyParameterObject)
Then
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim selected_name As String = ListBox1.SelectedItem()
Dim selected_param as parameters = params(selected_name)
End Sub
Something like this should do it:
Public Sub find_object_by_user_test_name(ByVal description As String)
' assuming param is your list of parameter objects
For Each p In param
If p.user_test_name = description Then
TextBox1.Text = p.test
TestBox2.Text = p.test_name
...
Exit For
End If
Next
End Sub
A few notes about your code. First, you can't allow two objects to have the same user_test_name. Second, you can't use parameters as a variable name if you already have a class called parameters in your current namespace (which you do).
There is a simpler solution than any of these--just do the following:
Dim i as Integer = ListBox1.SelectedIndex
Then you can use i as an index to your original list of objects.