私は再びこの他の質問ArrayList
で説明したこの問題を解決しようとしています...違いは、今回は他の外部ファイルを使用して回避するなどの代替ソリューションを探していないことです本当の問題、私は本当にMy.SettingsとArrayListを使用してこれを修正したいと思います。ここでMy.Settingsについて何が起こっているのかを理解したいと思います!.
問題は、次のように設定を設定した場合です。
次に、設定に対して実行された変更は、次のアプリの実行時に保持されます。このコードは問題を示しています。
Public Class Test
Private Sub Test_Handler() Handles MyBase.Shown
' Create a temporal predefined ArrayList.
Dim tmpArrayList As New ArrayList(capacity:=10I)
With tmpArrayList
.Add({"Item0", 0.0F})
.Add({"Item1", 0.5F})
End With
' Check the setting status.
If My.Settings.MRU Is Nothing Then
Debug.WriteLine("MRU setting is null.")
Debug.WriteLine("Initializing the Setting...")
My.Settings.MRU = New ArrayList(capacity:=10I)
ElseIf My.Settings.MRU.Count = 0 Then
Debug.WriteLine("MRU is not null but the ArrayList is empty.")
Debug.WriteLine("Adding some items...")
My.Settings.MRU = tmpArrayList.Clone
ElseIf My.Settings.MRU.Count > 0 Then ' This part of the block will never thrown.
Debug.WriteLine("MRU setting is OK.")
Debug.WriteLine("Item Count: " & CStr(My.Settings.MRU.Count))
Threading.Thread.Sleep(Integer.MaxValue)
End If
Debug.WriteLine("Saving any changes")
My.Settings.Save()
Debug.WriteLine("Updating any changes")
My.Settings.Reload()
Debug.WriteLine(String.Empty)
Debug.WriteLine("****************************************")
Debug.WriteLine("Checking again the MRU setting status in...")
For Count As Integer = 1 To 3
Debug.WriteLine(CStr(Count) & New String("."c, Count))
Threading.Thread.Sleep(TimeSpan.FromSeconds(1))
Next
Debug.WriteLine("****************************************")
Debug.WriteLine(String.Empty)
Me.Test_Handler()
End Sub
End Class
誰かが ArrayList が実際に保存されない理由を理解するように教えてくれたり、この問題を解決する方法を教えてくれませんか?.
アップデート
この問題を解決するために、このシリアル化可能なクラスを作成しました。
''' <summary>
''' A Class intended to use it as an Item for a MRU item collection that stores the item filepath, with additional info.
''' </summary>
<Serializable()>
Public Class MostRecentUsedItem
''' <summary>
''' Gets or sets the item filepath.
''' </summary>
''' <value>The file path.</value>
Public Property FilePath As String
''' <summary>
''' (Optionally) Gets or sets the item index.
''' </summary>
''' <value>The index.</value>
Public Property Index As Integer
''' <summary>
''' (Optionally) Gets or sets the item image.
''' </summary>
''' <value>The image.</value>
Public Property Img As Bitmap
''' <summary>
''' (Optionally) Gets or sets the item last-time open date.
''' </summary>
''' <value>The index.</value>
Public Property [Date] As Date
''' <summary>
''' (Optionally) Gets or sets the item tag.
''' </summary>
''' <value>The tag object.</value>
Public Property Tag As Object
End Class
また、この問題を解決するために、次のヘルパー関数を作成しました。
''' <summary>
''' Determines whether an object can be XML serialized.
''' </summary>
''' <param name="Object">The object.</param>
''' <returns><c>true</c> if object is XML serializable; otherwise, <c>false</c>.</returns>
Private Function IsObjectSerializable(ByVal [Object] As Object) As Boolean
Using fs As New IO.FileStream(IO.Path.GetTempFileName, IO.FileMode.Create)
Dim Serializer As New Xml.Serialization.XmlSerializer([Object].GetType)
Try
Serializer.Serialize(fs, [Object])
Return True
Catch ex As InvalidOperationException
Return False
End Try
End Using
End Function
このように設定を初期化した時点で、シリアル化可能です。
My.Settings.MRU = New ArrayList
文字列を追加した時点では、まだシリアライズ可能です。
My.Settings.MRU.Add("test string")
しかし、シリアル化可能なクラス、または のような他の種類のデータ型を追加しようとするとString()
、ArrayList は次のように非シリアル化を開始します。
My.Settings.MRU.Add({"Collection", "Of", "Strings"})
または、このように:
Dim MRUItem As New MostRecentUsedItem
MRUItem.FilePath = "C:\Test.ext"
My.Settings.MRU.Add(MRUItem)
...したがって、ArrayList の内容は次回の実行時に保持されず、シリアル化できません。
また、設定タイプをSystem.Collections.ArrayList
からSystem.Object
(必死に) に変更しようとしたので、これを実行できるようになりましたが、問題は解決しません。次のアプリの実行時にコレクションが保存されないことを意味します。
My.Settings.MRU = New List(Of MostRecentUsedItem)
Dim MRUItem As New MostRecentUsedItem
MRUItem.FilePath = "C:\Test.ext"
My.Settings.MRU.Add(MRUItem)