Search code examples
vb.netmy.settingssystem.version

Can't save type System.Version to My.Settings


I have a small test project for checking application version from a server and prompting a user to update. Everything works fine except that I can't save a type of System.Version to My.Settings. (I want to save the new version in case a user requests not to be reminded about it again.)

Now, I know I can save Version as a string and convert it back and forth - which I have done to get around this problem - but as System.Version is listed in the available setting data types, I figure it should work. But instead of saving the version, it merely saves an XML entry "Version" without a value (refer below).

I'm using VB.NET, VS 2013, .NET 4.

Here's some code to look at:

Settings.Designer.vb

<Global.System.Configuration.UserScopedSettingAttribute(),  _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
Public Property DoNotRemindVersion() As Global.System.Version
    Get
        Return CType(Me("DoNotRemindVersion"),Global.System.Version)
    End Get
    Set
        Me("DoNotRemindVersion") = value
    End Set
End Property

Example assignment

If My.Settings.DoNotRemind Then My.Settings.DoNotRemindVersion = oVersion.NewVersion

(oVersion.NewVersion is of type System.Version.)

As saved in user.config

<setting name="DoNotRemindVersion" serializeAs="Xml">
    <value>
        <Version xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
    </value>
</setting>

So, what am I doing wrong? I've read a few posts about having to serialize classes to save them to user settings, but this is a simple Version number, which, on the face of things, I would expect to be a supported data type.


Solution

  • The System.Version Class is marked with the SerializableAttribute but you will need to mark the property with the SettingsSerializeAsAttribute and pass the System.Configuration.SettingsSerializeAs.Binary value.

    You can not use the Project Settings designer interface to automatically generate the code like you have found in the Settings.designer.vb file. You will need to extend the My Namespace - MySettings Class yourself. This is one of areas that partial classes are useful.

    Add a new class file to your project and name something creative like CustomMySettings. Select and delete the auto-generated code in this new file and replace it with the following code.

    Namespace My
        Partial Friend NotInheritable Class MySettings
            ' The trick here is to tell it serialize as binary
            <Global.System.Configuration.SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Binary)> _
            <Global.System.Configuration.UserScopedSettingAttribute(), _
            Global.System.Diagnostics.DebuggerNonUserCodeAttribute()> _
            Public Property DoNotRemindVersion() As Global.System.Version
                Get
                        Return CType(Me("DoNotRemindVersion"), Global.System.Version)
                End Get
                Set(value As Global.System.Version)
                        Me("DoNotRemindVersion") = value
                End Set
            End Property
        End Class
    End Namespace
    

    This will allow you to use My.Settings.DoNotRemindVersion just like if you created the setting via the designer. The first time you access the setting, it will have a null (Nothing) value, so you may what to initialize it with something like the following in a Form.Load event handler.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim savedVersion As Version = My.Settings.DoNotRemindVersion
        If savedVersion Is Nothing Then
            My.Settings.DoNotRemindVersion = New Version(1, 0)
            My.Settings.Save()
        End If
    End Sub