Hello Members of DaniWeb,

I have run into an issue and need help solving it. I know how to go about adding items to My.Settings and I have already created the Specialized String Collection to My.Settings called List but I am having some trouble getting the items and the subitems to save to the list. If anyone could shoot me a snippet code on how this is done I would greatly appreciate it. Thanks

-Chris

I have tried using this code but keep getting an error when I close the program. All it says in a message box is "An error has occured"

For Each myItem As String In ListView1.Items
            My.Settings.List.Add(myItem)
        Next
        My.Settings.Save()
Member Avatar for Unhnd_Exception

Don't know about the specialized string collection. but.

First of all I don't use My.Settings. I use my own custom settings class. I like to group my settings and I like the extra functionality.

Heres an example of a custom settings class. It will work the same as My.Settings.

First create a new windows form app. Name a Form FormTest. Add a class to the project named TestSettings.

In the TestSettings Class add the following code.

Imports System.Configuration

Public Class TestSettings : Inherits ApplicationSettingsBase

    'Add the UserScopedSetting so it can be change
    'There is also the ApplicationScopedSetting.
    'The same as my.settings.
    'Can also set the default setting with DefaultSettingValue
    <UserScopedSetting(), DefaultSettingValue("1")> _
    Property MyInteger() As Integer
        Get
            Return Me("MyInteger")
        End Get
        Set(ByVal value As Integer)
            Me("MyInteger") = value
        End Set

    End Property

End Class

You now have a "My.Settings" class

In the FormTest Form add the following

Public Class FormTest
    'Create an instance of the custom settings class
    Private MyOwnSettings As New TestSettings

    Private Sub FormTest_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'When you press the close button the settings will be saved
        'Next time the value will be plus 1
        MyOwnSettings.MyInteger += 1
        MyOwnSettings.Save()
    End Sub

    Private Sub FormTest_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Load the setting from the custom settings file.
        Label1.Text = MyOwnSettings.MyInteger
    End Sub


End Class

Your custom settings class should be working now.


So with that I mind I went to create a class to save ListViewItems. The first thing i did was this.

Imports System.Configuration

Public Class ListViewSettings: Inherits ApplicationSettingsBase

<UserScopedSetting()> _
Property ListViewItems() As List(Of ListViewItem)
        Get
            If Me("ListViewItems") Is Nothing Then
                Me("ListViewItems") = New List(Of ListViewItem)
            End If
            Return Me("ListViewItems")
        End Get
        Set(ByVal value As List(Of ListViewItem))
            Me("ListViewItems") = value
        End Set
    End Property
End Class

But that doesn't work. I guess listviewitem can't be xml serialized by default. If that was a list of integer or something else it would of been fine.

I do know that the ListViewItem can easily be serialized with the binary formatter. With that in mind I made a different settings class to save the listview settings with the binary formatter.

Here it is

Imports System.Configuration

    Public Class Settings_ListView : Inherits ApplicationSettingsBase

    'Store the items while the class has an instance.
    Private fpListViewItems As List(Of ListViewItem)

    'I removed the UserScoped attribute because this isn't actually getting
    'saved.  The binary version will be saved.
    'Readonly because it doesn't matter when an object is a reference type.
    'You can still dispose, make null, or change the value with the get part.
    ReadOnly Property ListViewItems() As List(Of ListViewItem)
        Get
            If fpListViewItems Is Nothing Then
                'Load the binary formatted listview items into the list.
                fpListViewItems = New List(Of ListViewItem)
                fpListViewItems.AddRange(DeserializeListViewItems)
            End If
            Return fpListViewItems
        End Get

    End Property

    'This will do the saving.  It saves the listviewitems by 
    'using the binaryformatter class and then converts the bytes
    'to a base64 string.  You may just want to make this a byte()
    'property and skip the convert.FromBase64String as in derserialzeListviewItems.
    <UserScopedSetting()> _
    Public Property ListViewInBinaryFormBase64String() As String
        Get
            Return Me("ListViewInBinaryFormBase64String")
        End Get
        Set(ByVal value As String)
            Me("ListViewInBinaryFormBase64String") = value
        End Set
    End Property

    Public Overrides Sub Save()

        'Overriding when saved.  Instead of saving the listviewitems themselves
        'save a binary formatted version of them.
        SerializeListViewItems()

        MyBase.Save()
    End Sub

    Private Sub SerializeListViewItems()

        If fpListViewItems.Count = 0 Then
            Me("ListViewInBinaryFormBase64String") = String.Empty
        End If

        'Create a binary formatter and serialize the items
        Dim ListViewItemFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
        Dim FormattingStream As New IO.MemoryStream


        ListViewItemFormatter.Serialize(FormattingStream, fpListViewItems.ToArray)

        'I converted the bytes to a string.  You could probably change the property to a byte array instead
        Me("ListViewInBinaryFormBase64String") = Convert.ToBase64String(FormattingStream.ToArray)

        FormattingStream.Dispose()
        FormattingStream = Nothing
        ListViewItemFormatter = Nothing
    End Sub

    Private Function DeserializeListViewItems() As ListViewItem()

        If String.IsNullOrEmpty(Me.ListViewInBinaryFormBase64String) Then
            Return New ListViewItem() {}
        End If

        Dim ListViewItemFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
        Dim FormattingStream As IO.MemoryStream = Nothing
       
        Dim ListViewItems() As ListViewItem

        Try
            'change the string back to a byte array and deserialize it.
            FormattingStream = New IO.MemoryStream((Convert.FromBase64String(Me("ListViewInBinaryFormBase64String"))))

            ListViewItems = CType(ListViewItemFormatter.Deserialize(FormattingStream), ListViewItem())

            Return ListViewItems

        Catch ex As Exception
            Return New ListViewItem() {}
        Finally
            If FormattingStream IsNot Nothing Then
                FormattingStream.Dispose()
            End If
        End Try
        
    End Function

    End Class

And a form that uses it.

Public Class Form1

    Private MyOwnSettings As New Settings_ListView

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Load the custom saved items
        ListView1.Items.AddRange(MyOwnSettings.ListViewItems.ToArray)
    End Sub

    Private Sub ButtonAddThreeItems_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonAddThreeItems.Click
        'Add three items
        Dim ListViewItem As ListViewItem
        For i = 1 To 3
            ListViewItem = ListView1.Items.Add("Item" & CStr(i))
            ListViewItem.SubItems.Add(CStr(i))
        Next
    End Sub

    Private Sub ButtonSaveThreeItems_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSaveThreeItems.Click
        'Save the listview's items in the custom settings file
        'Create a copy of the items and add them to the custom settings file

        Dim ItemsToSave(ListView1.Items.Count - 1) As ListViewItem
        ListView1.Items.CopyTo(ItemsToSave, 0)

        MyOwnSettings.ListViewItems.Clear()
        MyOwnSettings.ListViewItems.AddRange(ItemsToSave)

        'You can save them now but you could also save them when the 
        'form close or in application shutdown.
        MyOwnSettings.Save()
    End Sub

End Class

Theres probably other ways to do it but this is what i thought of. Didn't spend to much time debugging but you should have to many issues if any.


With my own custom settings classes I have a module name AppSettings and in that module I declare an instance of each and access them with AppSettings.ASettingsClass
and I save them in the ApplicationShutdown of the ApplicationEvents Class.

Thanks for the lengthy, yet much needed reply ;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.