I have an array of a structure.
It's declared like this
Public SongsList as New List(Of Song)
"Song" it's structure's name.
It has 2 variables : path and name;
I'm wondering how I can sort this array by the name.
Public Structure Song
Public Path as String
Public Name as String
End Structure
I tried this
ListBox1.Items.Clear()
Dim sorted = SongsList.OrderBy(Function(s) s.Name).ToList
Dim i As Integer
For i = 0 To sorted.Count - 1
ListBox1.Items.Add(sorted(i).Name.ToString)
Next
But it throws a NullReferenceException.
This is how I'm adding items to SongsList
Dim open As New OpenFileDialog
open.Title = "Add songs"
open.Filter = "MP3 Files(*.mp3)|*.mp3"
open.Multiselect = True
ListBox1.Items.Clear()
If open.ShowDialog = DialogResult.OK Then
For Each SelectedSong As String In open.FileNames
i += 1
Dim songToAdd As New Song
songToAdd.Path = SelectedSong.ToString
songToAdd.Name = GetSafeFileName(SelectedSong.ToString)
SongsList.Add(songToAdd)
ListBox1.Items.Add(SongsList(i).Path)
Next
End If
You can use a Lambda expression. It uses the field you select in the OrderBy function. Lets Override the ToString method to tell the Listbox what to display, then you can just set the list as the datasource.
The class:
Public Class Song
Public Property Path as String
Public Property Name as String
Public Overrides Function ToString() As String
Return Me.Path
End If
End Class
Usage:
Dim open As New OpenFileDialog
open.Title = "Add songs"
open.Filter = "MP3 Files(*.mp3)|*.mp3"
open.Multiselect = True
If open.ShowDialog = DialogResult.OK Then
For Each SelectedSong As String In open.FileNames
Dim songToAdd As New Song
songToAdd.Path = SelectedSong
songToAdd.Name = GetSafeFileName(SelectedSong.ToString)
SongsList.Add(songToAdd)
Next
End If
Listbox1.DataSource = SongsList.OrderBy(Function(s) s.Name).ToList
*Very similar to OneFineDay's answer...
You don't need a custom class, just use a List(Of FileInfo):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim open As New OpenFileDialog
open.Title = "Add songs"
open.Filter = "MP3 Files(*.mp3)|*.mp3"
open.Multiselect = True
If open.ShowDialog = DialogResult.OK Then
ListBox1.DataSource = Nothing
Dim songs As New List(Of FileInfo)
For Each SelectedSong As String In open.FileNames
songs.Add(New FileInfo(SelectedSong))
Next
songs = songs.OrderBy(Function(fi) fi.Name).ToList
ListBox1.DataSource = songs
ListBox1.DisplayMember = "Name"
ListBox1.ValueMember = "FullName"
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If ListBox1.SelectedIndex <> -1 Then
Dim fi As FileInfo = DirectCast(ListBox1.SelectedItem, FileInfo)
Dim name As String = fi.Name
Dim fullPath As String = fi.FullName
Debug.Print("name = " & name)
Debug.Print("fullPath = " & fullPath)
End If
End Sub
Related
I'm trying to write the array persons to a file and read it and have no clue on how to go about it. Here's my code:
Public Class Form1
Structure Person
Public name As String
Public height As Integer
Public weight As Double
End Structure
Dim persons(49) As Person
Dim arraySize As Integer = 0
Private Sub submitBtn_Click(sender As Object, e As EventArgs) Handles submitBtn.Click
If arraySize < 50 Then
Dim Name As String
Dim Height As Integer
Dim Weight As Double
Name = nameTxt.Text
Height = CInt(heightTxt.Text)
Weight = CDbl(weightTxt.Text)
nameTxt.Text = Nothing
heightTxt.Text = Nothing
weightTxt.Text = Nothing
arraySize += 1
persons(arraySize).name = Name
persons(arraySize).height = Height
persons(arraySize).weight = Weight
Else
MsgBox("The list of people is full now. You may no longer enter new people.")
End If
End Sub
Private Sub saveBtn_Click(sender As Object, e As EventArgs) Handles saveBtn.Click
End Sub
Private Sub readBtn_Click(sender As Object, e As EventArgs) Handles readBtn.Click
End Sub
End Class
Any help on how to code this would be appreciated. Thank you!
I tried coding it to save the array persons (which is linked to the structure Person) to a file, but the app freezes, and i am not sure how to get around it.
try to use list :
Public Class Form1
<Serializable()> Structure Person
Public name As String
Public height As Integer
Public weight As Double
End Structure
dim persons As List(Of Person)
Private Sub submitBtn_Click(sender As Object, e As EventArgs) Handles submitBtn.Click
If persons.length < 50 Then
Dim Name As String
Dim Height As Integer
Dim Weight As Double
Name = nameTxt.Text
Height = CInt(heightTxt.Text)
Weight = CDbl(weightTxt.Text)
nameTxt.Text = Nothing
heightTxt.Text = Nothing
weightTxt.Text = Nothing
person.name = Name
person.height = Height
person.weight = Weight
persons.add(person)
Else
MsgBox("The list of people is full now. You may no longer enter new people.")
End If
End Sub
Private Sub saveBtn_Click(sender As Object, e As EventArgs) Handles saveBtn.Click
Using fs As New IO.FileStream("d:\backup\persons.dat", IO.FileMode.Create)
Dim formatter As New BinaryFormatter
formatter.Serialize(fs, persons)
End Using
End Sub
Private Sub readBtn_Click(sender As Object, e As EventArgs) Handles readBtn.Click
Using fs As New IO.FileStream("d:\backup\persons.dat", IO.FileMode.Open)
Dim formatter As New BinaryFormatter
persons = DirectCast(formatter.Deserialize(fs), List(Of person))
End Using
End Sub
dont forget to add <Serializable()> in front of struc definition.
I have following json data:
{
"cgFinishing": {
"a3colorfn": [{
"type": "Cacah",
"kode": "CCH"
},
{
"type": "Cutting",
"kode": "CUT"
}
]
}
}
And my JSON Class:
Public Class A3colorfn
Public Property type As String
Public Property kode As String
End Class
Public Class CgFinishing
Public Property a3colorfn As A3colorfn()
End Class
Public Class CGSave
Public Property cgFinishing As CgFinishing
End Class
I want to write a method in VB.NET that pull values from this JSON array using JSON.NET. This code works for me:
Public Sub fillCBfromJson(ByVal cb As ComboBox, json As Object, Optional ByVal value As String = "", Optional display As String = "")
....
End Sub
But I'd like to replace json As Object with something that are more specific, because I'd like to retrieve the count of items in the array (something like Count or GetLength, I cannot expose those property with Object type)
For your reference this code works for me...
Dim count As Integer = jsonObj.cgFinishing.a3colorfn.GetLength(0)
But I have no idea to turn it as a method.
Any help is appreciated.
More code listing:
Private Sub PublishDigital_Load(sender As Object, e As System.EventArgs) Handles MyBase.Load
jsonPath = Application.StartupPath + "\Addons\CG_Tools\cgSave.json"
jsonObj = JsonConvert.DeserializeObject(Of CGSave)(File.ReadAllText(jsonPath))
initfinishingA3()
End Sub
Public Sub initfinishingA3() 'I want to make this as a method, so I'll only need to input the Array object as argument.
Dim cbdata As Object = jsonObj.cgFinishing.a3colorfn '<- I want to put this line as argument instead
Dim count As Integer = jsonObj.cgFinishing.a3colorfn.GetLength(0)
Dim myCb As New List(Of CheckBox)
For Each cur In cbdata
Dim cb = New CheckBox()
tb_finishinga3.Controls.Add(cb)
Dim txt As JObject = JsonConvert.DeserializeObject(Of JObject)(JsonConvert.SerializeObject(cur))
...
cb.Text = txt("type")
...
Next
End Sub
Following method I wrote does not work..
Public Sub fillTabwithCB(ByVal cbdata As JArray, XOffset As Integer, YOffset As Integer, maxRow As Integer)
Dim count As Integer = cbdata.Count
Dim loopIndex As Integer
Dim i As Integer = 0
Dim myCb As New List(Of CheckBox)
For Each cur In cbdata
Dim cb = New CheckBox()
tb_finishinga3.Controls.Add(cb)
Dim txt As JObject = JsonConvert.DeserializeObject(Of JObject)(JsonConvert.SerializeObject(cur))
.........
cb.Text = txt("type")
..........
Next
End Sub
Then I tried it in this line...
fillTabwithCB(jsonObj.cgFinishing.a3colorfn, 7, 7, 5)
It generates following error:
Value of type '1-dimensional array of
CG_FileManagement.A3colorfn' cannot be converted to
'Newtonsoft.Json.Linq.JArray'.
Im currently working on getting this piece of code to work so that I can read a text file, move the contents into an array and then display a certain column (such as price)
Imports System.IO
Public Class Form1
Dim FileName As String
Dim i As Integer = 0
Dim Alpha As Integer = 0
Dim Products(31) As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FileName = "Products.txt"
End Sub
Private Sub btnCreateArray_Click(sender As Object, e As EventArgs) Handles btnCreateArray.Click
Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("Products.txt")
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(",")
Dim currentRow As String()
While Not MyReader.EndOfData
currentRow = MyReader.ReadFields()
Dim currentField As String
For Each currentField In currentRow
'MsgBox(currentField)
'txtShowNo.Text = currentField
'txtShowP.Text = i
i = i + 1
Products(i) = currentField
Next
End While
End Using
Do While Alpha <= i
If InStr((txtFileSearch.Text), (Products(Alpha))) Then
lstDisplayFile.Items.Add(Products(Alpha))
Alpha = Alpha + 1
End If
Loop
End Sub
Private Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click
txtFileSearch.Text = ""
End Sub
Private Sub btnAddToFilePrintFile_Click(sender As Object, e As EventArgs) Handles btnAddToFilePrintFile.Click
Dim Name As String
Dim SName As String
Dim IDNo As Integer
Name = txtName.Text
SName = txtSName.Text
IDNo = txtIDNo.Text
FileOpen(1, FileName, OpenMode.Append) ' create a new empty file & open it in append mode'
WriteLine(1, IDNo, Name, SName) ' Writes a line of data'
FileClose(1)
txtName.Text = ""
txtSName.Text = ""
txtIDNo.Text = ""
txtName.Focus()
End Sub
End Class
The program crashes on this line of code:
lstDisplayFile.Items.Add(Products(Alpha))
along with the following message :
An unhandled exception of type 'System.ArgumentNullException' occurred in System.Windows.Forms.dll
Alpha is my counter, and my thought process behind this was that if the input within the textbox is currently in the array, it will display the completed text in the array.
Here is the current contents within my text file :
"£5.00","50"
"£2.50","30"
If anyone could help me solve this I would be appreciative :)
I have a Serializable class called SettingsForProgram this class contains a list of string called ServerList
I am using this class to save settings for myprogram (username , password , colors , etc..) but when i try to save a list the same way then add -or get- items from it i get object reference not set to instance of object so how can i create a new instance of the class when converting it
To understand what i mean here are some codes :
The class :
<Serializable()>
Public Class SettingsForProgram
Private Namev As String = ""
Private pwv As String = ""
Public LocationsList As New List(Of String)
Private Savev As New Boolean()
Public Property LoginName As String
Get
Return Namev
End Get
Set(value As String)
Namev = value
End Set
End Property
Public Property LoginPassword As String
Get
Return pwv
End Get
Set(value As String)
pwv = value
End Set
End Property
Public Property SaveLogin As Boolean
Get
Return Savev
End Get
Set(value As Boolean)
Savev = value
End Set
End Property
Public Sub New()
LocationsList = New List(Of String)
End Sub
End Class
To load settings:(where i want to initialize the new instance of the class)
public MySettings as new SettingsForProgram
Public Sub LoadSettings()
Dim formatter As New BinaryFormatter()
Dim data As Byte() = File.ReadAllBytes(savepath)
Dim ms As New MemoryStream(data)
MySettings = CType(formatter.Deserialize(ms), SettingsForProgram)
End Sub
To save settings :
Public Sub SaveSettings()
Dim bf As New BinaryFormatter()
Dim ms As New MemoryStream()
If MySettings.LoginName = Nothing Then
MySettings.LoginName = "name"
ElseIf MySettings.LoginPassword = Nothing Then
MySettings.LoginPassword = "password"
End If
bf.Serialize(ms, MySettings)
Dim mySaveState As Byte() = ms.ToArray()
File.WriteAllBytes(savepath, mySaveState)
End Sub
I made a quick test like this
button 1 : save
MySettings.LocationsList.AddRange({"test1", "test2", "test3"}) <<<< where i get the error
SaveSettings()
button 2 : load
LoadSettings()
MsgBox(MySettings.LocationsList(1))
thanks to #Steve i now know the problem
, the solution is to do like i did with name and password saving ,
just added this to the save Settings
If MySettings.LocationsList Is Nothing Then
MySettings.LocationsList = New List(Of String)
MySettings.LocationsList.Add("Location 1")
End If
and every thing worked
final code
Public Sub SaveSettings()
Dim bf As New BinaryFormatter()
Dim ms As New MemoryStream()
If MySettings.LoginName = Nothing Then
MySettings.LoginName = "name"
ElseIf MySettings.LoginPassword = Nothing Then
MySettings.LoginPassword = "password"
End If
If MySettings.LocationsList Is Nothing Then
MySettings.LocationsList = New List(Of String)
MySettings.LocationsList.Add("Location 1")
End If
bf.Serialize(ms, MySettings)
Dim mySaveState As Byte() = ms.ToArray()
File.WriteAllBytes(savepath, mySaveState)
End Sub
I had a similar question for DatagridComboboxColumn but that shown me how to use the .itemsource to bind to an array outside of the datagrid. I am having a problem trying to bind to the collection that the datagrid is bound to at runtime.
I have included a working test program for how I am approaching this.
Class MainWindow
Dim ServerInfoArray As List(Of ServerInfo) = New List(Of ServerInfo)
Private Sub GetInfo(ByVal list As List(Of String))
For Each server As String In list
Dim tempip As ComboBoxItem = New ComboBoxItem
Dim tempip2 As ComboBoxItem = New ComboBoxItem
Dim sinfo As ServerInfo = New ServerInfo
tempip.Content = "192.129.123.23"
tempip2.Content = "23.213.223.21"
sinfo.IPArray.Items.Add(tempip)
sinfo.IPArray.Items.Add(tempip2)
sinfo.ServerName = server
ServerInfoArray.Add(sinfo)
DataGrid1.Items.Refresh()
Next
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim serverlist As List(Of String) = New List(Of String)
serverlist.Add("Test")
serverlist.Add("Random")
serverlist.Add("Local")
GetInfo(serverlist)
End Sub
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim Col_Serial As DataGridTextColumn = New DataGridTextColumn()
Col_Serial.Binding = New Binding("Servername")
Col_Serial.Header = "Servername"
Col_Serial.Width = 40
Dim Col_IPArray = New DataGridComboBoxColumn()
Col_IPArray.Header = "IP Addresses"
Col_IPArray.IsReadOnly = True
'Col_IPArray.ItemsSource = serverInfoArray ' Don't know how to do this.
Col_IPArray.SelectedValuePath = "IPArray"
Col_IPArray.DisplayMemberPath = "IPArray"
DataGrid1.Columns.Add(Col_Serial)
DataGrid1.Columns.Add(Col_IPArray)
DataGrid1.ItemsSource = ServerInfoArray
End Sub
End Class
Class ServerInfo
Dim _Servername As String
Dim _IPArray As ComboBox
Public Property Servername() As String
Get
Return _Servername
End Get
Set(ByVal value As String)
_Servername = value
End Set
End Property
Public Property IPArray As ComboBox
Get
Return _IPArray
End Get
Set(ByVal value As ComboBox)
_IPArray = value
End Set
End Property
Public Sub New()
_Servername = Nothing
_IPArray = New ComboBox
End Sub
End Class
I can get all Strings and Boolean to bind.
I do not know how I can bind this DataGridComboBoxColumn to the list of attached on the property. I cannot use XAML as I need to do this at runtime.
Dim Col_Serial As DataGridComboColumn = New DataGridComboColumn()
Col_Serial.ItemSource = GetData();
Col_Serial.SelectedValuePath = "ID_value";
Col_Serial.DisplayMemberPath = "displya_col";
Col_Serial.Header = "Disk4"
Col_Serial.Width = 40
Col_Serial.IsEnabled= false;
dg.Columns.Add(Col_serial);