2

この空のプロパティを設定しました:

ここに画像の説明を入力

しかし、新しいArrayListオブジェクトをプロパティに割り当てた後でも、アプリケーションの実行ごとにプロパティは常に空のままです。

MyBase.Loadイベントのハンドラーで、この問題をテストするためだけに、このメソッドを呼び出します。

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

上記のコードでわかるように、新しい ArrayList に 1 つのエントリを割り当てていますが、変更はそのアプリケーションの実行中にのみ有効になります。アプリを終了すると、プロパティは再び空になります。

そしてもちろん、私はこのオプションをチェックしました:

ここに画像の説明を入力

とにかく、設定を手動でコードに保存しているので、それは不要なので...

なぜこれが起こるのですか?

どうすればこの問題を解決できますか?.

アップデート:

私が調査したところ、これは既知の問題であり、Arrays、ArrayLists、および Generic collections(Of Type) を my.settings で保存できないようです (一方、StringCollection は保存できます)。

しかし、この投稿の最後の回答(MemoryStream の回答) では、ArrayList の変更を my.settings に永続的に保存し、次のアプリケーション実行でそれを読み取る簡単な方法について説明しています。

答えは非常に良いようですが、コードと続行する手順で少し迷っているので、そこで説明されている手順を誰かが説明できますが、人間が読める言語でお願いします。

ArrayList が次のアプリケーションの実行に残っていることを確認しました。はい、しかし、MemoryStream に古い ArrayList が含まれている場合、現在行っていることは My.Settings の割り当てです。 ? を含むArraylists元の ArrayList の代わりに、より多くを含む Arraylist としての MRU 設定String()、およびとにかく、この方法で設定を保存した後に配列エントリをロードする方法?.

これは私がその答えから試したことです:

' 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)
4

1 に答える 1

2

arrayList (または List または Collection) にデータがあり、回避策として BinaryFormatter を見ている場合、My.Settings も使用する正当な理由はありません。ファイルを保存して名前を選択するだけの BinaryFormatter を介して行うことができます。

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)

設定を保存する:

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

ロード設定:

' 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

回避策として BF に頼る必要がある場合は、メモリ ストリームをファイル ストリームに置き換えると、My.Settings の必要性が完全になくなり、必要な場所にファイルを保存でき、バージョンによって変更されず、ユーザーが EXE 名を変更します。上記のファイル名の式を変更しない限り、またはその他のもの。

MRU ArrayList 以外のアプリの場合、その場所で Class を使用して、Settings と同じようにすべての設定を必要な場所に保存できます。Class を としてタグ付けするだけです<Serializable>。クラス全体を保存するための 1 行のコードと、それを再構成するための 1 行が残ります。いくつかの制限がありますが、克服するのは難しくありません。

Private myNewSettings As New myNewSettingsClass
...

bf.Serialize(fs, myNewSettings)

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

その他の状況では、必要に応じて XML シリアライザーまたは ProtoBuf-NET を使用できます。

プログラムの終了時に新しい設定を自動的に保存することもできます。 [プロジェクト プロパティ] --> [アプリケーション] --> [アプリケーション イベントの表示]をクリックします。左側のメニューから [アプリケーション イベント] を選択し、右側のイベント メニューから [ シャットダウン] を選択します。

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

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

同様に、Startupイベントでそれらを自動的にロードすることができます。

于 2014-07-29T11:42:50.373 に答える