Frage

Ich habe diese Leerheitseigenschaft festgelegt:

enter image description here

Aber nach der Zuweisung eines neuen Anordnungsliste Wenn Sie der Eigenschaft ein Objekt hinzufügen, ist die Eigenschaft bei jeder Anwendungsausführung immer noch leer.

In einem Handler von MyBase.Load Eventuell rufe ich diese Methode auf, nur um dieses Problem zu testen:

sub blahblah handles mybase.load
    me.CheckRecentFiles
end sub

Private Sub CheckRecentFiles()

    Try
        ' This throws an object not referenced exception 'cause always is empty.
        MsgBox(My.Settings.RecentFiles.Count)
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

    ' Just for testing, if the collection is empty then I instance a new ArrayList
    ' and I assign it to the property and I save it and exit from the application.
    ' But even doing this the property is always empty in the next execution.
    If My.Settings.RecentFiles Is Nothing Then

        My.Settings.RecentFiles = New ArrayList
        My.Settings.RecentFiles.Add({"test-Item1", "test-Item2", "Test-Item3"})
        My.Settings.Save()
        Application.Exit()

    End If

End Sub

Wie Sie im obigen Code sehen können, weise ich eine neue ArrayList mit einem Eintrag zu, aber die Änderungen werden nur während der Ausführung dieser Anwendung wirksam. Wenn ich die App verlasse, wird die Eigenschaft wieder leer.

Und natürlich habe ich auch diese Option aktiviert:

enter image description here

Aber das ist auf jeden Fall unnötig, da ich die Einstellung manuell im Code speichere, also ...

Warum passiert das?

Wie kann ich dieses Problem lösen?

AKTUALISIEREN:

Ich habe es untersucht und es scheint, dass dies ein bekanntes Problem ist, dass Arrays, ArrayLists und alle generischen Sammlungen (vom Typ) nicht von my.settings gespeichert werden können (eine StringCollection hingegen schon).

Aber in der letzten Antwort von dieser Beitrag (die MemoryStream-Antwort) erklärt eine einfache Möglichkeit, die Änderungen einer ArrayList dauerhaft in my.settings zu speichern und sie dann beim nächsten Anwendungslauf zu lesen.

Die Antwort scheint sehr gut zu sein, aber ich bin ein wenig verwirrt mit dem Code und den Schritten zum Fortfahren, also könnte jemand die dort erklärten Schritte erklären, aber bitte in einer für mich lesbaren Sprache?

Ich habe überprüft, dass die ArrayList beim nächsten Anwendungslauf erhalten bleibt, ja, aber ich bin mir nicht sicher, was ich mache, denn wenn der MemoryStream die alte ArrayList enthält, weise ich jetzt die My.Settings zu. MRU-Einstellung als Arraylist, die mehr enthält Arraylists stattdessen die ursprüngliche ArrayList, die a enthielt String() ?, und wie lade ich überhaupt die Array-Einträge, nachdem ich die Einstellung auf diese Weise gespeichert habe?

Folgendes habe ich anhand dieser Antwort versucht:

' Create the ArrayList
Dim tmpArrayList = New System.Collections.ArrayList
tmpArrayList.Add({"test-Item1-1", "test-Item1-2", "Test-Item1-3"})
tmpArrayList.Add({"test-Item2-1", "test-Item2-2", "Test-Item2-3"})

' Serialize the arraylist entries:
Dim formatter As Runtime.Serialization.IFormatter =
    New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms1 As New IO.MemoryStream
formatter.Serialize(ms1, tmpArrayList)

' Save the ArrayList
My.Settings.MRU = New ArrayList(ms1.ToArray) ' I think it hould be like that?

' Load the ArrayList contained in My.Settings.MRU (no idea)
War es hilfreich?

Lösung

Wenn Sie die Daten in einer Array-Liste (oder Liste oder Sammlung) haben und den BinaryFormatter als Problemumgehung verwenden, gibt es keinen guten Grund, auch My.Settings zu verwenden.Sie können das, was es tut, über den BinaryFormatter tun, der lediglich die Datei speichert und einen Namen auswählt.

Imports System.Runtime.Serialization.Formatters.Binary

Private MRUArrayList = New ArrayList
' file location
 myFile = System.IO.Path.Combine(Environment.GetFolderPath(Environment. _
                    SpecialFolder.ApplicationData),
                                    CompName,
                                    ProgramName,
                                    File)

Einstellungen speichern:

Dim bf As New BinaryFormatter
Using fs As New FileStream(myFile, FileMode.OpenOrCreate)
    bf.Serialize(fs, MRUArrayList )
End Using

Einstellungen laden:

' dont attempt for the first time run
If File.Exists(myFile) = False Then Return False

Dim bf As New BinaryFormatter
Using fs As New FileStream(myFile, FileMode.Open)
    MRUArrayList = CType(bf.Deserialize(fs), ArrayList)
End Using

Sobald Sie zur Problemumgehung auf BF zurückgreifen müssen, wird durch das Ersetzen des Memory Stream durch einen File Stream die Notwendigkeit von My.Settings vollständig beseitigt, Sie können die Datei an einem beliebigen Ort speichern und sie ändert sich nicht je nach Version, wenn der Benutzer den EXE-Namen ändert oder irgendetwas anderes, es sei denn, Sie ändern die Dateinamenformel oben.

Für eine App mit mehr als nur der MRU-ArrayList können Sie stattdessen eine Klasse verwenden, um alle Einstellungen an dem gewünschten Ort zu speichern, ganz ähnlich wie bei „Einstellungen“.Sie müssen die Klasse nur mit einem Tag versehen <Serializable>.Es bleibt eine Codezeile, um die gesamte Klasse zu speichern, und eine Zeile, um sie wiederherzustellen.Es gibt einige Einschränkungen, die jedoch nicht schwer zu überwinden sind.

Private myNewSettings As New myNewSettingsClass
...

bf.Serialize(fs, myNewSettings)

myNewSettings = CType(bf.Deserialize(fs), myNewSettingsClass )

In anderen Situationen können Sie je nach Bedarf den XML-Serializer oder ProtoBuf-NET verwenden.

Sie können Ihre neuen Einstellungen auch automatisch beim Beenden des Programms speichern lassen:Gehe zu Projekteigenschaften -> Anwendung -> Klicken Sie auf Anwendungsereignisse anzeigen.Wählen Sie „Anwendungsereignisse“ aus dem linken Menü und Abschalten aus dem rechten Ereignismenü.

Private Sub MyApplication_Shutdown(sender As Object, 
          e As EventArgs) Handles Me.Shutdown

   ' add your code to Save (above) here
End Sub

Ebenso können Sie sie automatisch in die laden lassen Startup Ereignis.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top