【问题标题】:Arraylist of custom classes inside My.SettingsMy.Settings 中自定义类的 Arraylist
【发布时间】:2011-04-26 15:34:48
【问题描述】:

我有一个 Visual Basic .Net 2.0 程序。我正在将设置从旧设置文件移动到 app.config 程序设置文件。我正在努力做到这一点。

所以,我添加了我的设置as shown in this image

加载时我这样做:

If My.Settings.databaseConnectionSettings Is Nothing Then
            My.Settings.databaseConnectionSettings = New ArrayList()
End If

这是我的自定义类:

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

而且,我就是这样使用它的:

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.'

那么,问题是,如何将我的 DatabaseConnectionSettings 的数组列表保存到持久存储中?我想以最干净的方式做到这一点。也就是说,我不想每次使用它时都必须将其转换为字符串或将其保存到单独的文件中。我希望能够使用 My.Settings 访问器方法。

请注意,它运行良好,只是没有保存到存储中。

【问题讨论】:

    标签: .net vb.net visual-studio-2005 settings


    【解决方案1】:

    Debug + Exceptions,勾选抛出的 CLR 异常框。您现在将看到出了什么问题。有几个例外,但交易破坏者是第二个,“类型......不是预期的”。

    需要属性来告诉 xml 序列化程序哪些类型存储在 ArrayList 中。这在MSDN Library page,“序列化 ArrayList”部分中进行了描述。问题是,您不能应用所需的 [XmlElement] 属性,因为 ArrayList 实例是在自动生成的代码中声明的。泛型 List(Of T) 没有相同的问题,但现在您会遇到设置设计器中的限制,它不支持泛型类型。

    嗯,这里是一块岩石和一个坚硬的地方,你无法完成这项工作。 StringCollection 是令人反感的选择。或者放弃为此使用设置的想法,而是自己使用 xml 序列化来完成。或者你喜欢的其他任何东西。

    【讨论】:

    • 我想通了。基本上,我为 ArrayList 创建了一个包装器。我使用该页面的“序列化 ArrayList”部分定义了它。然后我将其设为 ISerializable,但我不知道这是否需要。然后,我将包装类作为“设置”类型,购买浏览,然后键入带有名称空间的该类的完整路径。令人惊讶的是,大多数编程问题归结为在 IDE 中添加了额外的抽象级别(包装类)或错误(无法浏览我自己的 NAMESPACE)。和平!
    • 感谢快速破解,但我认为你会以每小时 250 英里的速度撞上一堵砖墙。您自己的命名空间中的类不可浏览是有充分理由的。 Build + Clean,Build + Build,我怀疑当编译器在它试图构建的程序集中找不到类型时,你的前灯会崩溃。解决方法是使用该类型创建一个类库项目,以便在编译设置代码时构建并使用它。
    • 好吧,您添加 My.Settings-settings 的表单似乎编辑了 Settings.Designer.vb 文件。 Settings.Designer.vb 文件是自动生成的代码。而且,它已经包含对我的项目命名空间的引用,因此它应该可以在编译时访问它。修复似乎有效。话虽如此,您使用类库项目的解决方案会更好。
    【解决方案2】:

    许多新手程序员,即使是高级程序员也不知道如何在 MYSETTINGS 中保存自定义课程。

    这是完美的解决方案

    1. 你创建了一个类,然后你想存储该文件
    2. 在 MYSETTINGS 中创建一个设置类型:数组列表
    3. 在代码中要保存时,需要获取类的内存流,序列化,使用格式化程序。

    示例

    Dim formatter As Runtime.Serialization.IFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
                Dim ms As New IO.MemoryStream
                formatter.Serialize(ms, original)
                Return ms
    
    1. 保存到数组列表中的 MYSETTINGS,添加 BYTE() 类型的值 喜欢:ms.ToArray

    这将工作,当应用程序。它关闭并再次打开,ARRAY() 仍将在我的设置中

    1. 现在当您想使用该值时 您需要使用格式化程序对字节进行反序列化。

    这是我创建的类,这有助于序列化、从您想要的任何对象获取内存流并反序列化。

    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
    

    如果您需要帮助或有疑问,请在此处发送电子邮件:

    bboyse aaron GmA IL doot com

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 2013-09-29
      • 2014-10-26
      • 2011-10-10
      • 1970-01-01
      • 2016-06-17
      相关资源
      最近更新 更多