質問

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

enter image description here

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

のハンドラーで 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

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

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

enter image description here

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

なぜこのようなことが起こるのでしょうか?

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

アップデート:

調査したところ、これは、配列、ArrayList、および汎用コレクション(Of Type)が my.settings で保存できないという既知の問題のようです(ただし、一方で StringCollection は保存できます)。

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

答えはとても良さそうですが、コードと次に進む手順が少し分からないので、誰かがそこで説明されている手順を人間が読める言語で説明してもらえますか?

ArrayList が次のアプリケーション実行時にも残ることを確認しました。はい、しかし、MemoryStream に古い ArrayList が含まれている場合、今私が行っていることは My.Settings の割り当てなので、何をしているのかわかりません。より多くの内容を含むアレイリストとしての MRU 設定 Arraylists 代わりに、元の ArrayList には 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)
役に立ちましたか?

解決

データが 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 に頼る必要がある場合は、Memory Stream を File Stream に置き換えることで、My.Settings の必要性が完全になくなり、ファイルをどこにでも保存できるようになり、バージョンによって変更されず、ユーザーが EXE 名を変更できるようになります。上記のファイル名の式を変更しない限り、他のものでも構いません。

MRU ArrayList 以外のアプリの場合は、設定と同じようにクラスを代わりに使用して、すべての設定を必要な場所に保存できます。クラスにタグを付けるだけです <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 イベント。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top