问题
I have a Visual Basic .Net 2.0 program. I'm moving the settings from an older settings file, to an app.config program settings file. I'm trying to do this as nicely as possible.
So, I added my setting as shown in this image.
On load I do this:
If My.Settings.databaseConnectionSettings Is Nothing Then
My.Settings.databaseConnectionSettings = New ArrayList()
End If
This is my custom class:
Imports System.Xml.Serialization
<Serializable()> Public Class DatabaseConnectionSettings
Private _nickname As String = String.Empty
Private _username As String = String.Empty
Private _password As String = String.Empty
Private _database As String = String.Empty
Private _server As String = String.Empty
Private _ssl As Boolean
Public Sub New()
_nickname = ""
_username = ""
_password = ""
_database = ""
_server = ""
_ssl = False
End Sub
Public Sub New(ByVal nickname As String, ByVal username As String, _
ByVal password As String, ByVal database As String, _
ByVal server As String, ByVal ssl As Boolean)
_nickname = nickname
_username = username
_password = password
_database = database
_server = server
_ssl = ssl
End Sub
Public Property nickname() As String
Get
Return _nickname
End Get
Set(ByVal Value As String)
_nickname = Value
End Set
End Property
Public Property username() As String
Get
Return _username
End Get
Set(ByVal Value As String)
_username = Value
End Set
End Property
Public Property password() As String
Get
Return _password
End Get
Set(ByVal Value As String)
_password = Value
End Set
End Property
Public Property database() As String
Get
Return _database
End Get
Set(ByVal Value As String)
_database = Value
End Set
End Property
Public Property server() As String
Get
Return _server
End Get
Set(ByVal Value As String)
_server = Value
End Set
End Property
<XmlElementAttribute(ElementName:="ssl")> Public Property ssl() As Boolean
Get
Return _ssl
End Get
Set(ByVal Value As Boolean)
_ssl = Value
End Set
End Property
End Class
And, this is how I use it:
Dim databaseSettings As New DatabaseConnectionSettings( _
Me.txtNickName.Text, Me.txtUser.Text, Me.txtPass.Text, Me.txtData.Text, _
Me.txtServer.Text, Me.chkSSL.Checked)
'This statement will increment the arraylist count'
My.Settings.databaseConnectionSettings.Add(databaseSettings)
'This statement will save everything but the array list'
My.Settings.Save()
'This statement reloads everything, but the array list. The array list count after this goes to zero.'
My.Settings.Reload() 'If I remove this, program works fine until next run.'
So, the question is, how do I get that arraylist of my DatabaseConnectionSettings saved to persistent storage? I want to do this in the cleanest way possible. That is, I don't want to have to convert it to a string or save it to a separate file every-time I want to use it. I would like to be able to use the My.Settings accessor method.
Note, it's working perfectly, except it's not being saved to storage.
回答1:
Debug + Exceptions, tick the Thrown box for CLR exceptions. You'll now see what is going wrong. There are several exceptions but the deal breaker is the second one, "The type ... was not expected".
Attributes are required to tell the xml serializer what types are stored in an ArrayList. This is described in this MSDN Library page, "Serializing an ArrayList" section. Problem is, you cannot apply the required [XmlElement] attribute since the ArrayList instance is declared in auto-generated code. A generic List(Of T) doesn't have the same problem, but now you'll smack into a restriction in the setting designer, it doesn't support generic types.
Well, a rock and a hard place here, you can't make this work. StringCollection is the distasteful alternative. Or ditch the idea of using Settings for this and just do it yourself with xml serialization. Or whatever else you prefer.
回答2:
MANY NOVICE PROGRAMMERS, EVEN ADVANCED ONES DOESNT KNOW HOW TO SAVE A CUSTOM CLASS IN MYSETTINGS.
HERE ITS THE PERFECT SOLUTION
- YOU CREATE THE CLASS AND SHIT YOU WANNA STORE
- CREATE A SETTING TYPE: ARRAYLIST IN MYSETTINGS
- IN CODE WHEN YOU WANT TO SAVE, YOU NEED TO GET MEMORYSTREAM OF THE CLASS, SERIALIZE, USE A FORMATTER.
EXAMPLE
Dim formatter As Runtime.Serialization.IFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms As New IO.MemoryStream
formatter.Serialize(ms, original)
Return ms
- SAVE TO MYSETTINGS IN ARRAYLIST, ADD VALUE OF TYPE BYTE()
LIKE :
ms.ToArray
THIS WILL WORK, AND WHEN THE APP. ITS SHUTDOWN AND OPENED AGAIN, THE ARRAY() WILL STILL BE IN MYSETTINGS
- NOW WHEN YOU WANT TO USE THE VALUE YOU NEED TO DESERIALIZE THE BYTES USING A FORMATTER.
HERE ITS THE CLASS I MADED, THIS HELPS TO SERIALIZE, GET MEMORYSTREAM FROM ANY OBJECT YOU WANT, AND DESERIALIZE.
Public Class SerializableObjectCopier(Of ObjectType)
Public Function GetMemoryStream(ByVal original As ObjectType) As IO.MemoryStream
Dim formatter As Runtime.Serialization.IFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms As New IO.MemoryStream
formatter.Serialize(ms, original)
Return ms
End Function
Public Function GetCopy(ByVal original As ObjectType) As ObjectType
Dim formatter As Runtime.Serialization.IFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms As New IO.MemoryStream
formatter.Serialize(ms, original)
ms.Seek(0, IO.SeekOrigin.Begin)
Return CType(formatter.Deserialize(ms), ObjectType)
End Function
Public Function GetCopy(ByVal ms As System.IO.MemoryStream) As ObjectType
Dim formatter As Runtime.Serialization.IFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
ms.Seek(0, IO.SeekOrigin.Begin)
Return CType(formatter.Deserialize(ms), ObjectType)
End Function
End Class
IF YOU NEED SOME HELP OR HAVE QUESTION HERE ITS MY EMAIL:
bboyse aaron GmA IL doot com
来源:https://stackoverflow.com/questions/3954447/arraylist-of-custom-classes-inside-my-settings