My.Settings不保存一个ArrayList [英] My.Settings does not save an ArrayList

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

问题描述

我这个emptynes​​s属性:

但在分配一个新的的ArrayList 对象的属性,该属性始终还是空在每一个应用程序的执行。

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

 子blahblah处理mybase.load
    me.CheckRecentFiles
端子

私人小组CheckRecentFiles()

    尝试
        这不是抛出异常引用的对象的原因始终是空的。
        MSGBOX(My.Settings.RecentFiles.Count)
    抓住EX为例外
        MSGBOX(ex.Message)
    结束尝试

    只是为了测试,如果集合为空,那么我实例一个新的ArrayList
    我给它分配的财产,我将它保存并退出应用程序。
    但即使是这样的属性始终是空的,在未来的执行。
    如果My.Settings.RecentFiles是没有那么

        My.Settings.RecentFiles =新的ArrayList
        My.Settings.RecentFiles.Add({试验项目1,测试项目2,试验项目3})
        My.Settings.Save()
        Application.Exit()

    结束如果

结束小组
 

正如你可以在code见上面,我分配一个新的ArrayList有一个条目,但更改才生效的参加办法执行期间,如果从应用程序我退出则该属性变空了。

和还ofcourse我已经检查该选项:

但不管怎么说这是不必要的,因为我节省了code设置manualy,所以......

为什么会发生呢?

我如何解决这个问题?

  

更新:

我已经调查,似乎这是一个已知的问题,数组,的ArrayList和任何泛型集合(类型)不能由my.settings保存(但另一方面一StringCollection可以)

但在最后的答案<一href="http://stackoverflow.com/questions/3954447/arraylist-of-custom-classes-inside-my-settings">this帖子(将MemoryStream答案)介绍一个简单的方法来永久保存一个ArrayList来my.settings更改,然后看它在未来的应用程序运行。

答案似乎很不错,但我是一个有点与code丢失的步骤procceed,所以有人能解释的步骤有解释,但在人类可读的语言给我好吗?

我验证过的ArrayList保持在未来的应用程序运行,是的,但我不肯定我在做什么的原因,如果将MemoryStream包含旧的ArrayList然后我在做什么,现在是一个分配的我.Settings.MRU设置为包含一个ArrayList多个的ArrayList 而不是包含在字符串的渊源的ArrayList()?,反正和保存设置这种方式后,如何将这个数组项?

这是我从这个问题的答案已经尝试过:

 '创建的ArrayList
昏暗tmpArrayList =新System.Collections.ArrayList
tmpArrayList.Add({测试Item1-1,测试Item1-2,测试Item1-3})
tmpArrayList.Add({测试Item2-1,测试Item2-2,测试Item2-3})

序列化数组列表条目:
昏暗的格式作为Runtime.Serialization.IFormatter =
    新Runtime.Serialization.Formatters.Binary.BinaryFormatter
昏暗MS1作为新IO.MemoryStream
formatter.Serialize(MS1,tmpArrayList)

保存的ArrayList
My.Settings.MRU =新的ArrayList(ms1.ToArray)我认为这HOULD是这样的?

加载包含在My.Settings.MRU(不知道)ArrayList中
 

解决方案

如果您有数据一个ArrayList(或列表或集合),而你在看的BinaryFormatter的解决办法,也没有充分的理由还也可以使用My.Settings。你可以做它直通的BinaryFormatter的,它只是保存文件,并选择一个名称。

 进口System.Runtime.Serialization.Formatters.Binary

私人MRUArrayList =新的ArrayList
文件位置
 MYFILE = System.IO.Path.Combine(Environment.GetFolderPath(环境。_
                    SpecialFolder.ApplicationData)
                                    COMPNAME,
                                    ProgramName中,
                                    文件)
 

保存设置:

 昏暗bf的新的BinaryFormatter
使用FS作为新的FileStream(MYFILE,FileMode.OpenOrCreate)
    bf.Serialize(FS,MRUArrayList)
结束使用
 

加载设置:

 '不要企图首次运行
如果File.Exists(MYFILE)= false,那么返回假

昏暗的BF作为新的BinaryFormatter
使用FS作为新的FileStream(MYFILE,FileMode.Open)
    MRUArrayList = CTYPE(bf.Deserialize(FS),ArrayList中)
结束使用
 

在你不得不求助于BF的解决方法是,文件流摆脱了需要My.Settings完全更换内存流,可以存储任何你想要的文件,它不会通过的版本变化,用户改变EXE文件名或其他任何东西,除非你改变上面的文件名公式。

有关的应用程序有更多的不仅仅是MRU ArrayList中,你可以使用一个类在它的地方,所有的设置保存到您想要非常喜欢设置时的位置。你只需要标记的类为&LT;序列化&GT; 。它仍然一行code保存整个班级,一条线来重建它。有一定的局限性,但它们不是难以克服。

 私人myNewSettings作为新myNewSettingsClass
...

bf.Serialize(FS,myNewSettings)

myNewSettings = CTYPE(bf.Deserialize(FS),myNewSettingsClass)
 

在其他情况下,您可以根据需要的情况下使用XML序列化或protobuf网。

您也可以有你的新设置自动保存在程序退出时:转到项目属性 - >应用程序 - >点击查看应用程序事件。从左侧菜单中从右侧事件菜单中的应用程序事件,和关闭

 私人小组MyApplication_Shutdown(发件人为对象,
          E上EventArgs的)把手Me.Shutdown

   在这里添加您的code保存(上图)
结束小组
 

同样,你也可以把它自动加载他们在启动事件。

I've set this emptyness property:

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

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

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...

Why happens this?.

How I can solve this problem?.

UPDATE:

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)

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?

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)

解决方案

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)

Save Settings:

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

Load Settings:

' 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

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.

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 )

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

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆