I am developing an application to run from USB, is it like a dock/launcher application but I have a problem.
I want to use My.Settings class to save my app settings, but it saves the setting file in AppData folder e.g. C:\Users\<user_name>\AppData\Local\...\...\user.config
I don't want that. I want to save in a path and name of my defined, e.g. My.Application.Info.DirectoryPath & "\Settings.xml"
How can I achieve this?
Update Example of final XML:
<?xml version="1.0" encoding="utf-8"?>
<conf>
<pos>1</pos>
<btn index="1" value="D:\League of Legends\" perm="true">LeagueClient.exe</btn>
<btn index="2" value="D:\RuneLite\" perm="false">RuneLite.exe</btn>
<btn index="3" value="" perm="false"></btn>
<btn index="4" value="" perm="false"></btn>
</conf>
Full project in Github coming soon!!!
Work way for me :
Imports System.IO
Imports System.Xml
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ValConfFile()
End Sub
Public Sub ValConfFile()
If File.Exists("config.xml") = False Then : CreateConfXML() : End If
End Sub
Public Sub CreateConfXML()
Dim obj As Object
Dim archivo As Object
Dim x As Integer = 1
obj = CreateObject("Scripting.FileSystemObject")
archivo = obj.CreateTextFile("config.xml", True)
archivo.WriteLine("<?xml version='1.0' encoding='utf-8'?>")
archivo.WriteLine("<conf>")
archivo.WriteLine("<pos>1</pos>")
For x = 1 To 4
archivo.WriteLine("<btn index='" & CStr(x) & "' value='' perm='false'></btn>")
Next
archivo.WriteLine("</conf>")
archivo.Close()
End Sub
End Class
XML Serialization can be used for this, and is actually fairly straightforward. All you need to do is design one or more classes for your data, then apply the appropriate attributes (their name are in the form Xml...Attribute) in order to serialize them the way you want.
In this setup I've used four different attributes:
XmlElement - Usually the most common one. Specifies that a property will be serialized as an element of its own. The resulting name can be customized by setting the ElementName parameter in the constructor.
If used on lists or arrays, it applies to each item in the collection.
XmlRoot - Pretty much the same as XmlElement, but used for the root element (the class itself).
XmlAttribute - Specifies that a property will be serialized as an attribute (name="value") applied to the parent object, instead of as an element inside it.
XmlText - Specifies that a property's value will be serialized as the contents between the tags of the parent object (i.e. <object>property value</object>).
Imports System.IO
Imports System.Xml
Imports System.Xml.Serialization
<XmlRoot(ElementName:="conf")>
Public Class Config
<XmlElement(ElementName:="pos")>
Public Property Position As Integer
<XmlElement(ElementName:="btn")>
Public Property Buttons As New List(Of ConfigButton)
Public Sub New()
End Sub
Public Sub New(ByVal Position As Integer)
Me.Position = Position
End Sub
Public Shared Function Load(ByVal File As String) As Config
Using FStream As New FileStream(File, FileMode.Open, FileAccess.Read, FileShare.Read)
Dim Serializer As New XmlSerializer(GetType(Config))
Return Serializer.Deserialize(FStream)
End Using
End Function
Public Sub Save(ByVal File As String)
Using FStream As New FileStream(File, FileMode.Create, FileAccess.Write, FileShare.None)
Dim Serializer As New XmlSerializer(GetType(Config))
Serializer.Serialize(FStream)
End Using
End Sub
End Class
Public Class ConfigButton
<XmlText()>
Public Property DisplayName As String
<XmlAttribute("index")>
Public Property Index As Integer
<XmlAttribute("perm")>
Public Property Perm As Boolean
<XmlAttribute("value")>
Public Property Value As String
Public Sub New()
End Sub
Public Sub New(ByVal DisplayName As String, ByVal Value As String, ByVal Index As Integer, ByVal Perm As Boolean)
Me.DisplayName = DisplayName
Me.Value = Value
Me.Index = Index
Me.Perm = Perm
End Sub
End Class
Usage example:
Private cfg As Config
'
'Loading the config.
'
Private Sub Form1_Load(sender As Object, e As EventArgs) Handled MyBase.Load
If File.Exists("config.xml") Then
cfg = Config.Load("config.xml")
Else
cfg = New Config()
End If
End Sub
'
'Saving the config.
'
Private Sub Form1_FormClosed(sender As Object, e As EventArgs) Handles Me.FormClosed
cfg.Save("config.xml")
End Sub
Adding a button:
cfg.Buttons.Add(New ConfigButton("RuneLite.exe", "D:\RuneLite\", 2, False))
Iterating buttons:
For Each btn As ConfigButton In cfg.Buttons
MessageBox.Show(btn.DisplayName)
Next
Removing a button at a specific index:
'Removes the fourth button.
cfg.Buttons.RemoveAt(3)
Related
Using the code below I can create a box with a combo box that shows the current com ports
What I need to do is show what is attached to the com Port, for example I want it to list
COM PORT1 FTDI USB serial adapter, the reason is to let you the user know which port to enter in a batch file that runs when another button is clicked ( i have removed that part of the code as its not important)
I have done some google work and found this link http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/331a26c1-0f42-4cf1-8adb-32fb09a18953/ But that just errors out
Imports System
Imports System.Threading
Imports System.IO.Ports
Imports System.ComponentModel
Public Class Form1
'------------------------------------------------
Dim myPort As Array
Delegate Sub SetTextCallback(ByVal [text] As String) 'Added to prevent threading
errors during receiveing of data
'------------------------------------------------
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
myPort = IO.Ports.SerialPort.GetPortNames()
ComboBox1.Items.AddRange(myPort)
End Sub
End Class
The following shows how to get a list of COM devices in VB.NET for both .NET 6 and .NET Framework 4.8 in VS 2022. If a USB COM (serial port) device is added/removed, the ComboBox will be updated.
Option 1 - Windows Forms App: (.NET 6)
Create a new project: Windows Forms App (name: SerialPortGetComDevices)
Download/install the following NuGet packages:
System.IO.Ports
System.Management
Option 2 - Windows Forms App (.NET Framework) - v4.8:
Create a new project: Windows Forms App (.NET Framework) (name: SerialPortGetComDevices)
Add Reference:
In VS menu, click Project
Select Add Reference...
Select Assemblies
Check System.Management
Click OK
The instructions below are the same for both Windows Forms App and Windows Forms App (.NET Framework) (ie: the instructions below are the same regardless of which option you've chosen above).
Create a class (name: ComPortInfo.vb)
In VS menu, select Project
Select Add Class... (name: ComPortInfo.vb)
Click Add
ComPortInfo.vb:
Public Class ComPortInfo
Public Property Caption As String
Public Property PortName As String
End Class
Open Solution Explorer:
In VS menu, click View
Select Solution Explorer
Open Properties Window:
In VS menu, click View
Select Properties Window
Add Load Event Handler
In Solution Explorer, right-click Form1.vb and select View Designer.
In Properties Window, click
Double-click Load
Add FormClosing Event Handler
In Solution Explorer, right-click Form1.vb and select View Designer.
In Properties Window, click
Double-click FormClosing
Add a ComboBox to the Form (name: ComboBoxComPorts)
In VS menu, click View
Select Toolbox
In Toolbox, select ComboBox, and drag it to the Form.
In the Properties Window, change (Name) to ComboBoxComPorts
In the Properties Window, change DropDownStyle to DropDownList
Select one of the options below. The 1st option uses ManagementEventWatcher to detect USB device insertion and removal. The 2nd option overrides WndProc.
Note: The WndProc version (Option 2) seems to have slightly better performance.
Option 1 (ManagementEventWatcher)
Note: The code for detecting the insertion and removal of a USB device, is adapted from here.
Add the code below in your Form (ex: Form1.vb)
Form1.vb
Imports System.ComponentModel
Imports System.Management
Imports System.IO.Ports
Public Class Form1
'create new instance
Private _comPorts As BindingList(Of ComPortInfo) = New BindingList(Of ComPortInfo)
Private _managementEventWatcher1 As ManagementEventWatcher = New ManagementEventWatcher()
Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitializeManagementEventWatcher()
UpdateCOM()
'set properties
ComboBoxComPorts.DataSource = _comPorts
ComboBoxComPorts.DisplayMember = "Caption"
ComboBoxComPorts.ValueMember = "PortName"
End Sub
Private Sub GetComPorts()
'this method Is only called from 'UpdateCOM'
'_comPorts' is only modified in this method
Dim portDict As Dictionary(Of String, String) = New Dictionary(Of String, String)
'clear existing data
_comPorts.Clear()
'get port names
For Each pName As String In SerialPort.GetPortNames()
If Not portDict.ContainsKey(pName) Then
portDict.Add(pName, pName) 'add to Dictionary
End If
Next
'get USB COM ports - this may result in a more descriptive name than 'COM1'
Using searcherPnPEntity As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT Name FROM Win32_PnPEntity WHERE PNPClass = 'Ports'")
For Each objPnPEntity As ManagementObject In searcherPnPEntity.Get()
If objPnPEntity Is Nothing Then
Continue For
End If
'get name
Dim name As String = objPnPEntity("Name")?.ToString()
If Not String.IsNullOrEmpty(name) AndAlso name.ToUpper().Contains("COM") Then
Dim portName As String = name.Substring(name.IndexOf("(") + 1, name.IndexOf(")") - name.IndexOf("(") - 1)
If Not portDict.ContainsKey(portName) Then
portDict.Add(portName, name) 'add to Dictionary
Else
portDict(portName) = name 'update value
End If
End If
Next
End Using
'add items from Dictionary to BindingList
For Each kvp As KeyValuePair(Of String, String) In portDict
_comPorts.Add(New ComPortInfo() With {.Caption = kvp.Value, .PortName = kvp.Key}) 'add
Next
End Sub
Private Sub InitializeManagementEventWatcher()
'see https:'learn.microsoft.com/en-us/windows/win32/wmisdk/within-clause
'WITHIN sets the polling interval in seconds
'polling too frequently may reduce performance
Dim query As WqlEventQuery = New WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity'")
'Dim query As WqlEventQuery = New WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_PnPEntity'")
'set property
_managementEventWatcher1.Query = query
'subscribe to event
AddHandler _managementEventWatcher1.EventArrived, AddressOf ManagementEventWatcher_EventArrived
'start
_managementEventWatcher1.Start()
End Sub
Private Sub LogMsg(msg As String, Optional includeTimestamp As Boolean = True)
If includeTimestamp Then
msg = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff")} - {msg}"
End If
Debug.WriteLine(msg)
End Sub
Public Sub UpdateCOM()
If ComboBoxComPorts.InvokeRequired Then
'LogMsg("ComboBoxComPorts.InvokeRequired")
ComboBoxComPorts.Invoke(New MethodInvoker(Sub()
GetComPorts()
End Sub))
Else
GetComPorts()
End If
End Sub
Public Sub ManagementEventWatcher_EventArrived(sender As Object, e As EventArrivedEventArgs)
Dim obj As ManagementBaseObject = DirectCast(e.NewEvent, ManagementBaseObject)
Dim target As ManagementBaseObject = If(obj("TargetInstance") IsNot Nothing, DirectCast(obj("TargetInstance"), ManagementBaseObject), Nothing)
Dim usbEventType As String = String.Empty
Select Case target.ClassPath.ClassName
Case "__InstanceCreationEvent"
usbEventType = "added"
Case "__InstanceDeletionEvent"
usbEventType = "removed"
Case Else
usbEventType = target.ClassPath.ClassName
End Select
If target("PNPClass") IsNot Nothing AndAlso target("PNPClass").ToString() = "Ports" Then
'update COM ports
UpdateCOM()
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
'stop
_managementEventWatcher1.Stop()
'unsubscribe from event
RemoveHandler _managementEventWatcher1.EventArrived, AddressOf ManagementEventWatcher_EventArrived
End Sub
End Class
Option 2 (override WndProc)
Note: The code for detecting the insertion and removal of a USB device, is adapted from here.
Add a Module (name: UsbDeviceNotification.vb)
In VS menu, select Project
Select Add Module... (name: UsbDeviceNotification.vb)
Click Add
UsbDeviceNotification.vb
Imports System.Runtime.InteropServices
Module UsbDeviceNotification
Public Const DbtDeviceArrival As Integer = &H8000 'device added
Public Const DbtDeviceRemoveComplete As Integer = &H8004 'device removed
Public Const WM_DEVICECHANGE As Integer = &H219 'device change event
Public Const DBT_DEVTYP_DEVICEINTERFACE As Integer = 5
Private ReadOnly _guidDevInterfaceUSBDevice As Guid = New Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED") 'USB devices
Private _notificationHandle As IntPtr
Declare Auto Function RegisterDeviceNotification Lib "user32" (recipient As IntPtr, notificationFilter As IntPtr, flags As Integer) As IntPtr
Declare Auto Function UnregisterDeviceNotification Lib "user32" (hwnd As IntPtr) As Boolean
<StructLayout(LayoutKind.Sequential)>
Private Structure DEV_BROADCAST_DEVICEINTERFACE
Dim Size As Integer
Dim DeviceType As Integer
Dim Reserved As Integer
Dim ClassGuid As Guid
Dim Name As Short
End Structure
Public Sub RegisterUsbDeviceNotification(hwnd As IntPtr)
'Registers a window to receive notifications when USB devices are plugged or unplugged.
Dim dbi As DEV_BROADCAST_DEVICEINTERFACE = New DEV_BROADCAST_DEVICEINTERFACE() With
{
.DeviceType = DBT_DEVTYP_DEVICEINTERFACE,
.ClassGuid = _guidDevInterfaceUSBDevice
}
dbi.Size = Marshal.SizeOf(dbi)
Dim buffer As IntPtr = Marshal.AllocHGlobal(dbi.Size)
Marshal.StructureToPtr(dbi, buffer, True)
_notificationHandle = RegisterDeviceNotification(hwnd, buffer, 0)
End Sub
Public Sub UnregisterUsbDeviceNotification()
UnregisterDeviceNotification(_notificationHandle)
End Sub
End Module
Add the code below in your Form (ex: Form1.vb)
Form1.vb
Imports System.ComponentModel
Imports System.Management
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
'create new instance
Private _comPorts As BindingList(Of ComPortInfo) = New BindingList(Of ComPortInfo)
Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
UpdateCOM()
'set properties
ComboBoxComPorts.DataSource = _comPorts
ComboBoxComPorts.DisplayMember = "Caption"
ComboBoxComPorts.ValueMember = "PortName"
End Sub
Private Sub GetComPorts()
'this method Is only called from 'UpdateCOM'
'_comPorts' is only modified in this method
Dim portDict As Dictionary(Of String, String) = New Dictionary(Of String, String)
'clear existing data
_comPorts.Clear()
'get port names
For Each pName As String In SerialPort.GetPortNames()
If Not portDict.ContainsKey(pName) Then
portDict.Add(pName, pName) 'add to Dictionary
End If
Next
'get USB COM ports - this may result in a more descriptive name than 'COM1'
Using searcherPnPEntity As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT Name FROM Win32_PnPEntity WHERE PNPClass = 'Ports'")
If searcherPnPEntity IsNot Nothing Then
For Each objPnPEntity As ManagementBaseObject In searcherPnPEntity.Get()
If objPnPEntity Is Nothing Then
Continue For
End If
'get name
Dim name As String = objPnPEntity("Name")?.ToString()
If Not String.IsNullOrEmpty(name) AndAlso name.ToUpper().Contains("COM") Then
Dim portName As String = name.Substring(name.IndexOf("(") + 1, name.IndexOf(")") - name.IndexOf("(") - 1)
If Not portDict.ContainsKey(portName) Then
portDict.Add(portName, name) 'add to Dictionary
Else
portDict(portName) = name 'update value
End If
End If
Next
End If
End Using
'add items from Dictionary to BindingList
For Each kvp As KeyValuePair(Of String, String) In portDict
_comPorts.Add(New ComPortInfo() With {.Caption = kvp.Value, .PortName = kvp.Key}) 'add
Next
End Sub
Private Sub LogMsg(msg As String, Optional includeTimestamp As Boolean = True)
If includeTimestamp Then
msg = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff")} - {msg}"
End If
Debug.WriteLine(msg)
End Sub
Public Sub UpdateCOM()
'since this method/Sub is called from WndProc,
'it needs to run on a new thread
Dim threadProc As System.Threading.Thread = New System.Threading.Thread(Sub()
If ComboBoxComPorts.InvokeRequired Then
'LogMsg("ComboBoxComPorts.InvokeRequired")
ComboBoxComPorts.Invoke(New MethodInvoker(Sub()
GetComPorts()
End Sub))
Else
GetComPorts()
End If
End Sub)
threadProc.SetApartmentState(System.Threading.ApartmentState.STA)
threadProc.Start()
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = UsbDeviceNotification.WM_DEVICECHANGE Then
Select Case CInt(m.WParam)
Case UsbDeviceNotification.DbtDeviceRemoveComplete
UpdateCOM()
Case UsbDeviceNotification.DbtDeviceArrival
UpdateCOM()
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
End Sub
End Class
The following PowerShell commands may also provide useful information.
PowerShell:
Get-CimInstance -Namespace Root\Cimv2 -Query "Select * From Win32_SerialPort Where Name like '%COM%'"
Get-CimInstance -Namespace Root\Cimv2 -Query "Select * From Win32_SerialPortConfiguration"
Get-CimInstance -Namespace Root\Cimv2 -Query "Select * From Win32_PnPEntity where PnPClass = 'Ports' and Name like '%COM%'"
mode
Resources:
System.IO.Ports Namespace
SerialPort Class
BindingList Class
ManagementEventWatcher Class
WITHIN Clause
Detecting USB drive insertion and removal using windows service and c#
Check for device change (add/remove) events
ComboBox Class
Dictionary<TKey,TValue> Class
ManagementObjectSearcher Class
ManagementObject Class
Win32_PnPEntity class
For...Next Statement (Visual Basic)
If Operator (Visual Basic)
My VB.NET junk cleaner cannot delete aria-Debug-10144.log since it is used by another process.
I tried this:
Imports System.Collections.ObjectModel
Imports System.IO
Public Class Form1
Dim TempDirs As ReadOnlyCollection(Of String)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TempDirs = (My.Computer.FileSystem.GetDirectories("C:\Users\Aitor\AppData\Local\Temp"))
Dim ListDirs As List(Of String) = TempDirs.ToList
Dim directoryName As String = "C:\Users\Aitor\AppData\Local\Temp"
For Each deleteFile In Directory.GetFiles(directoryName, "*.*", SearchOption.TopDirectoryOnly)
If Not deleteFile.ToString = "aria-Debug-10144.log" Then
File.Delete(deleteFile)
End If
Next
MsgBox("Clean completed!", MsgBoxStyle.OkOnly + MsgBoxStyle.Information, "Results")
End Sub
End Class
But it still tries to do it.
Can anybody help me?
There are two reasons:
Firstly, the selected file is being occupied by another program. In this case, you need to determine whether the selected file is occupied before deleting it. Here is a small example.
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("kernel32.dll")>
Public Shared Function _lopen(ByVal lpPathName As String, ByVal iReadWrite As Integer) As IntPtr
End Function
<DllImport("kernel32.dll")>
Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
End Function
Public Const OF_READWRITE As Integer = 2
Public Const OF_SHARE_DENY_NONE As Integer = &H40
Public Shared ReadOnly HFILE_ERROR As IntPtr = New IntPtr(-1)
Public Shared Function IsFileOccupied(ByVal filePath As String) As Boolean
Dim vHandle As IntPtr = _lopen(filePath, OF_READWRITE Or OF_SHARE_DENY_NONE)
CloseHandle(vHandle)
Return If(vHandle = HFILE_ERROR, True, False)
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If (IsFileOccupied("C:\Users\juliex\AppData\Local\Temp\aria-debug-13836.log")) Then
MessageBox.Show("File is already occupied")
Else
MessageBox.Show("File is not occupied")
'Then do some delete operation.
End If
End Sub
End Class
Secondly, the selected file is a temporary file and is currently locked. If you want to clear the temporary files it owns, you need to have full control to unlock these files and then delete them!
You should be very careful if you want to delete the TEMP file, whether it is owned by the application or by another owner. The original application may have applied the lock because it wanted to use the file!
At this time you can refer to this link below:
1.How can I unlock a file that is locked by a process in .NET
2.https://social.msdn.microsoft.com/Forums/vstudio/en-US/9e2044c5-ae5d-4552-a335-01cc567dfc58/how-to-unlock-a-file-used-by-other-process?forum=csharpgeneral
I am using VS2008/.net fw 3.5sp1 and back into the coding life - and a little rusty to say the least :) Any help on the below would be great please.
I need to gather a list of input from a user, that I will work with later (pass to a teradata DWH with some other values). The input list involves two parts, a BSB ID and an Account ID. After some research it looks like the best option would be to create a class for the accounts, a list of accounts and bind that to a datagridview - of which I have done - but it looks like I can't add/edit. I have added a new button/add button to alter the data grid and get an error that I cannot programmatically add.
When I use accountList.AllowNew() = TRUE -- Error -- constructor on type bankaccount not found - but - I thought the constructor is the "new" sub in the class?
When I try accountsBindingSource.IsFixedSize = False it advises the property is read only.
For this - I've cut all the other code out to just this section, which requires one form (frmAccountLoad), with a datagridview dgvAccounts and a button btnNewLine.
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
Imports System.Diagnostics
Imports System.Drawing
Imports System.Data.SqlClient
Imports System.Windows.Forms
'--------------------------------------------------------------------
Public Class frmAccountLoad
' This BindingSource binds the list to the DataGridView control.
Private accountsBindingSource As New BindingSource()
Private Sub frmAccountLoad_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Create list to hold accounts
Dim accountList As New BindingList(Of BankAccount)
accountList.AllowNew() = True
'accountList.AllowEdit = True
accountsBindingSource.DataSource = accountList
dgvAccounts.DataSource = accountsBindingSource
'dgvAccounts.Columns(0).HeaderText = "BSB"
'dgvAccounts.Columns(1).HeaderText = "Account"
End Sub
Private Sub btnNewLine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNewLine.Click
'accountsBindingSource.IsFixedSize = False
accountsBindingSource.AddNew()
End Sub
End Class
'--------------------------------------------------------------------
Public Class BankAccount
'----------------------------------------------------------
'a bank account has both a BSB and an account number
Private m_BSB As String
Private m_Account As String
'----------------------------------------------------------
'Public Property
Public Property BSB() As String
Get
Return m_BSB
End Get
Set(ByVal value As String)
m_BSB = value
End Set
End Property
Public Property Account() As String
Get
Return m_Account
End Get
Set(ByVal value As String)
m_Account = value
End Set
End Property
'----------------------------------------------------------
Public Sub New(ByVal new_Bsb As String, ByVal new_Account As String)
m_BSB = new_Bsb
m_Account = new_Account
End Sub
End Class
To be able to call AddNew on your BindingList the BankAccount should have a parameter-less constructor.
You need to have a public parameter-less constructor if you need some initialization, or just remove any constructor if you don't need initialization, then the default parameter-less constructor will be used.
Public Class BankAccount
Public Property BSB As String
Public Property Account As String
Public Sub New()
'Do initialization here if you need
'Or Remove the constructor if you don't need any initialization.
End Sub
End Class
Also you don't need to set accountList.AllowNew = True. It's enough to use a BindingList(Of T) as DataSource.
Private accountList As BindingList(Of BankAccount)
Private Sub frmAccountLoad_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
accountList = New BindingList(Of BankAccount)
dgvAccounts.DataSource = BS
End Sub
Then you can call accountList.AddNew() wherever you need.
Is there away I can save or load a game a lot more easier than I have?
Saving Code
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("c:\Pugio Cadite\CharacterInformation.txt", True)
file.WriteLine(charactername)
file.WriteLine(characterrace)
file.WriteLine(characterclass)
file.WriteLine(characterGender)
file.WriteLine(charactergold)
file.WriteLine(characterlevel)
file.Close()
and I have not yet wrote the load function.
Imports System.Xml.Serialization
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'save the program variables
Dim p As New ProgramVars
p.Prop1 = "1"
p.Prop2 = "2"
p.Prop3 = "3"
p.Prop4 = "4"
Dim strFilename As String = "C:\Junk\Junk.xml"
p.Save(strFilename)
'load them into a different object
Dim p2 As ProgramVars = ProgramVars.Load(strFilename)
MsgBox(p2.Prop3)
End Sub
End Class
<Serializable>
Public Class ProgramVars
Property Prop1 As String
Property Prop2 As String
Property Prop3 As String
Property Prop4 As String
Sub Save(filename As String)
Using fs As New System.IO.FileStream(filename, IO.FileMode.OpenOrCreate)
Dim xs As New XmlSerializer(GetType(ProgramVars))
xs.Serialize(fs, Me)
End Using
End Sub
Shared Function Load(filename As String) As ProgramVars
Using fs As New System.IO.FileStream(filename, IO.FileMode.OpenOrCreate)
Dim xs As New XmlSerializer(GetType(ProgramVars))
Return xs.Deserialize(fs)
End Using
End Function
End Class
I'm using a collection and structure to store some parsed data in a class, but when i try to retrieve the data it is null. On form1 i'm i can get the response string which is all the raw data. Am I adding the parsed data to the collection correctly? Did I call it on form1 correctly?
Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
Dim dloader as new Downloader(blah)
'this does not work
Dim test as new _ListInfo
msgbox(test.Name) ' produces an empty message box
'this works
msgbox(dloader.Download)
End Sub
Here is my code for the class:
Public Structure _Info
Dim Name As String
End Structure
Public Class Downloader
Dim _ListCollection As New Collection(Of _ListInfo)
Public ReadOnly Property ListCollection() As Collection(Of _ListInfo)
Get
ListCollection = _ListCollection
End Get
End Property
Public Function Download() As String
'doing the download
ParseList()
Return _ResponseString
End Function
Private Sub ParseList()
_ListCollection.Clear()
Dim Name As String
Dim MyInfo As _ListInfo
MyInfo.Name = Name
_ListCollection.Add(MyInfo)
End Sub
Why do you expect it to work? You are just newing-up a structure and accessing a property. Don't you want to do something like:
Dim dloader as new Downloader(blah)
dloader.Download()
' Show first name.
MsgBox(dloader.ListCollection(0).Name)