WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Isolated Storage Basics
Pages: 1, 2

Saving User Settings

As I mentioned at the start of the article, one common use of isolated storage is to save user settings. To demonstrate this, I'll show you how to equip a form with size and location persistence. Although you can stick anything you want in isolated storage, in this case I'll take advantage of the .NET Framework's hooks for easy XML serialization and deserialization of objects by starting with a class to hold the information that I want to save:


<Serializable()> _
Public Class FormSettings
    Public Top As Integer
    Public Left As Integer
    Public Height As Integer
    Public Width As Integer
End Class

The basic strategy here is to create and save a FormSettings object when the form is closed, and to retrieve the saved object when it's opened. Here's the creation code, which I've placed in the form's Closing event handler so that it will be called whenever the user is finished with the form:


Private Sub Form1_Closing(ByVal sender As Object, _
 ByVal e As System.ComponentModel.CancelEventArgs) _
 Handles MyBase.Closing
    Try
        ' Get the isolated store for this assembly
        Dim isf As IsolatedStorageFile = _
         IsolatedStorageFile.GetUserStoreForAssembly()

        ' Create or truncate the settings file
        ' This will ensure that only the object we're
        ' saving right now will be in the file
        Dim isfs1 As IsolatedStorageFileStream = _
         New IsolatedStorageFileStream("FormSettings.xml", _
         FileMode.Create, FileAccess.Write, isf)

        ' Construct an object and tell it about the form
        Dim fs As FormSettings = New FormSettings
        fs.Top = Me.Top
        fs.Left = Me.Left
        fs.Height = Me.Height
        fs.Width = Me.Width

        ' Serialize the object to the file
        Dim xs As XmlSerializer = _
        New XmlSerializer(GetType(FormSettings))
        xs.Serialize(isfs1, fs)
        isfs1.Close()

    Catch ex As Exception
        ' If settings can't be saved, next 
        ' run will just the use form defaults
    End Try
End Sub

The other end of the process happens when the form is loaded:


Private Sub Form1_Load(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles MyBase.Load
    Try
        ' Get the isolated store for this assembly
        Dim isf As IsolatedStorageFile = _
         IsolatedStorageFile.GetUserStoreForAssembly()

        ' Open the settings file
        Dim isfs1 As IsolatedStorageFileStream = _
         New IsolatedStorageFileStream("FormSettings.xml", _
         FileMode.Open, FileAccess.Read, isf)

        ' Deserialize the XML to an object
        Dim fs As FormSettings = New FormSettings
        Dim xtr As XmlTextReader = New XmlTextReader(isfs1)
        Dim xs As XmlSerializer = _
         New XmlSerializer(GetType(FormSettings))
        fs = CType(xs.Deserialize(xtr), FormSettings)

        ' And apply the settings to the form
        Me.Top = fs.Top
        Me.Left = fs.Left
        Me.Height = fs.Height
        Me.Width = fs.Width

        ' Clean up
        isfs1.Close()
    Catch ex As Exception
        ' No file found. Just run with the existing settings
    End Try
End Sub

To see this code in action, create a new Visual Basic .NET Windows application, add the FormSettings.vb class, and place the event code behind the form. You'll need to add references to the appropriate namespaces as well:


Imports System.IO
Imports System.IO.IsolatedStorage
Imports System.Xml
Imports System.Xml.Serialization

Then run the application to display the default blank form. Move it anywhere on the screen and size it as you like. Close the form to exit the application. Now run it again. You'll find that the form comes back where you left it, instead of at its default location.

Note that very little of this code is related to the actual settings that I'm storing. If I decided in the future to add the form's background color, its caption text, or any other property to the list of things to persist, I could simply add another public property to the class and one line in each event procedure. The isolated storage and serialization plumbing takes care of everything else.

Choosing Isolated Storage

As with any other technique, there are good times and bad times to use isolated storage. Here are some typical applications where isolated storage can be a good fit:

  • Controls that will be downloaded from the Internet will generally not have permissions to write to a disk file. But they will have permissions to write to isolated storage, which is kept in a location where it can't hurt other things.
  • Isolated storage can also provide an answer for web applications that need to write large amounts of data on the client. For small amounts of data, you may find cookies provide a more straightforward solution--if the user accepts cookies.
  • Utility components that are shared by multiple applications can use isolated storage to keep track of persistent settings, such as the default folder the user prefers.
  • Because isolated storage stores are isolated by user, server applications can use this mechanism to dedicate unique settings storage for each individual user.
  • Applications designed to be used by roaming users can use isolated storage as a convenient way to create settings that roam with the user.

But while you're considering isolated storage, you also need to think about the potential drawbacks and pitfalls:

  • Isolated storage by itself doesn't provide secure storage for secrets of high value. The administrator can open the underlying disk files, or delete them entirely. You can work around this, if you desire, by using the cryptography classes to encrypt data stored in isolated storage.
  • Isolated storage may impose significant overhead, in the form of duplicate files, if it's used for settings that do not change from user to user. This makes it less well-suited for large amounts of data that must be shared between users.
  • Because administrators can set isolated storage quotas, you cannot count on having any particular amount of isolated storage available to your applications. This means that error-handling is a must in isolated storage code. Of course, you should be handling errors in all your code as a matter of course.
  • Code must have the IsolatedStorageFilePermission to work with isolated storage. This can be a problem if your machine is severely locked down by administrative security policies.

I think you'll find it worth taking the time to understand isolated storage, especially if you still recall the joy of trying to find a file or registry location that worked as a universal place to save settings in previous development environments. In this, as in so many other ways, the .NET Framework has done an admirable job of providing functionality that just works the way it should.

Mike Gunderloy is the lead developer for Larkware and author of numerous books and articles on programming topics.


Return to ONDotnet.com