本文介绍了My.Settings 不保存 ArrayList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置了这个空性属性:

I've set this emptyness property:

但是在为该属性分配一个新的 ArrayList 对象后,该属性在每次应用程序执行中始终为空.

But after assigning a new ArrayList object to the property, the property always still empty in every application execution.

MyBase.Load 事件的处理程序中,我调用了这个方法,只是为了测试这个问题:

In a handler of MyBase.Load event I do a call to this method, just for testing this issue:

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 分配一个条目,但更改仅在该应用程序执行期间生效,如果我退出应用程序,则该属性再次变为空.

As you can see in the code above I'm assigning a new ArrayList with one entry, but the changes only take effect during that appplication execution, if I exit from the app then the property goes empty again.

当然我也勾选了这个选项:

And also ofcourse I've checked this option:

但无论如何这是不必要的,因为我正在代码中手动保存设置,所以...

But anyways that is unnecessary since I'm saving the setting manualy in the code, so...

为什么会这样?.

我该如何解决这个问题?.

How I can solve this problem?.

更新:

我已经调查过,似乎这是一个已知问题,即 my.settings 无法保存数组、ArrayLists 和任何通用集合(类型)(但另一方面 StringCollection 可以)

I've investigated and seems that this is a known problem that Arrays, ArrayLists and any Generic collections(Of Type) can't be saved by the my.settings (but on the other hand a StringCollection can)

但是在这篇文章的最后一个答案中(MemoryStreamanswer) 解释了一种将 ArrayList 的更改永久保存到 my.settings 的简单方法,然后在下一次应用程序运行时读取它.

But in the last answer of this post (the MemoryStream answer) explains an easy way to permanently save the changes of an ArrayList to my.settings and then read it in the next application run.

答案似乎非常好,但我对代码和执行步骤有点迷茫,所以有人可以解释那里解释的步骤,但请用人类可读的语言为我解释?

The answer seems very good, but I'm a little bit lost with the code and the steps to procceed, so someone could explain the steps explained there but in a human-readable language for me please?

我已经确认 ArrayList 保留在下一次应用程序运行中,是的,但我不确定我在做什么,因为如果 MemoryStream 包含旧的 ArrayList 那么我现在正在做的是分配 My.Settings.MRU 设置为包含更多 Arraylists 的 Arraylist 而不是包含 String() 的原始 ArrayList ?,以及无论如何如何在保存设置后加载数组条目这样?.

I've verified that the ArrayList remains in the next application run, yes but I'm not sure of what I'm doing 'cause if the MemoryStream contains the old ArrayList then what I'm doing now Is assigning the My.Settings.MRU setting as an Arraylist that contains more Arraylists instead the originaly ArrayList that contained a String() ?, and anyways how to load the array entries after saving the setting this way?.

这是我从那个答案中尝试过的:

This is what I've tried from that answer:

' 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 执行它的操作,它只是保存文件并选择一个名称.

If you have the data in an arrayList (or List or Collection), and you are looking at the BinaryFormatter for the workaround, there is no good reason to also also use My.Settings. You can do what it does thru the BinaryFormatter, which is just saving the file and picking a name.

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 名称或其他任何内容,除非您更改上面的文件名公式.

Once you have to resort to BF for the workaround, replacing the Memory Stream with a File Stream gets rid of the need for My.Settings entirely, lets you store the file wherever you want and it wont change by version, user changing the EXE name or anything else unless you change the file name formula above.

对于不仅仅是 MRU ArrayList 的应用程序,您可以在其位置使用类将所有设置存储到您想要的位置,就像设置一样.您只需要将类标记为 .它仍然是一行代码来保存整个类,一行代码来重构它.有一些限制,但不难克服.

For an App with more than just the MRU ArrayList, you can use a Class in its place to store all the settings to the location you want very much like Settings does. You just need to tag the Class as <Serializable>. It remains one line of code to save the entire class, one line to reconstitute it. There are some limitations, but they are not difficult to overcome.

Private myNewSettings As New myNewSettingsClass
...

bf.Serialize(fs, myNewSettings)

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

在其他情况下,您可以根据情况使用 XML 序列化程序或 ProtoBuf-NET.

In other situations, you can use the XML serializer or ProtoBuf-NET as needed for the situation.

您还可以在程序退出时自动保存新设置:转到项目属性 --> 应用程序 --> 单击查看应用程序事件.从左侧菜单中选择应用程序事件",然后从右侧事件菜单中选择关闭.

You can also have your new settings automatically saved when the program exits: Go to Project Properties --> Application --> Click View Application Events. Select "Application Events" from the left menu, and ShutDown from the right event menu.

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

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

同样,您可以让它在 Startup 事件中自动加载它们.

Likewise you can have it automatically load them in the Startup event.

这篇关于My.Settings 不保存 ArrayList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 07:22