saving and loading controls

psolms

Member
Joined
Apr 23, 2008
Messages
14
Programming Experience
Beginner
hey everyone, i have a windows application.
i am using custom controls on a panel.
i need to be able to save and load all the information from all the controls.
what is the easiest way to do this?

thanks in advance.

psolms
 
yes that is true. plus i have a variable number of custom controls on a panel that can be added and taken away at will. (minimum of 1 control)
and it has to all save to 1 file...

is there some resource that i should be using? or are the standard libraries in VS 2005 going to be ok?
 
What you're talking about is handled by the Framework but it's not a simple example. You can serialise objects to XML or binary files in a couple of lines of code, but complex types require you to add extra code to control what gets serialised and how. In the tradition of OOP, this serialisation behaviour is encapsulated within the type itself, so serialising a complex object is no more difficult than serialising a simple object. You should read about "custom serialization" on MSDN.
 
ok.. i read up a little on the documentation you reccomended.
ill be honest though, i dont really understand how to implement it.

im actually not even sure that this is what im talking about.

let me try a more simple problem, and i should be able to scale it myself.

i have a form with a button, 3 textboxes (each with user inputed text) and a group of 3 radio buttons.
i want to be able to save all of this to a text file (file.txt) and be able to load it in the program so that the default textboxes text will be replaced by the values in the file, as well as the radio button that was checked at save time, as well as the button.enabled property.

hopefully that makes the problem more clear.
it seems to me that it would be relativly easy, but i just need to know what to do to save, and how to load.

thanks so much.
 
So you don't want to save the Location, Size, BackColor, etc. property values of the Button and TextBoxes? It's just the data they display and a few choice properties?
 
i dont know why that makes any difference.. or is it the difference between serialization and something else?

those property values are nice, but not necissary.
for the most part, they do not change from the defaults.
the important data is the text
 
If we ask questions we ask them for a reason, so answering them clearly and correctly the first time is a good idea. I asked basically the same question several posts ago and you said yes. If you don;t need them then you really should have said then. The reason is that there's no point serialising an object with 100 properties if you only need 10 of them. In that case you'd create your own type to store only those 10 properties and then serialise that. In your case, if you only have a small number of values to save out of a very complex object with potentially hundreds of nested properties then you would do just that. Create your own type with a property for each value you want to save and then serialise an instance of that type.
 
ok, that seems to make sense. do you mean create my own class and serialise an instance of the class? and how do i save the instance as a file?
and consequently, how do i de-serialise from the file?
 
There are different ways of doing this, more or less advanced/generic. There is also Xml serialization and binary serialization.

Here is the most basic example, a structure is defined with one field for each one info to be preserved (notice the Serializable attribute), a SaveInfo method that populates the info from the controls and serialize to Xml, a LoadInfo method that serialize from Xml and populates the controls from the info.
VB.NET:
<Serializable()> Public Structure ControlsInfo
    Public textbox1text As String
    Public radiobutton1checked As Boolean
    Public radiobutton2checked As Boolean
    Public savebuttonenabled As Boolean
    'etc
End Structure

Sub SaveInfo()
    Dim ci As New ControlsInfo
    ci.textbox1text = Me.TextBox1.Text
    ci.radiobutton1checked = Me.RadioButton1.Checked
    ci.radiobutton2checked = Me.RadioButton2.Checked
    ci.savebuttonenabled = Me.SaveButton.Enabled
    Dim filename As String = IO.Path.Combine(Application.StartupPath, "ControlsInfo.xml")
    Using fs As New IO.FileStream(filename, IO.FileMode.Create, IO.FileAccess.Write)
        Dim ser As New Xml.Serialization.XmlSerializer(GetType(ControlsInfo))
        ser.Serialize(fs, ci)
    End Using
End Sub

Sub LoadInfo()
    Dim ci As ControlsInfo
    Dim filename As String = IO.Path.Combine(Application.StartupPath, "ControlsInfo.xml")
    Using fs As New IO.FileStream(filename, IO.FileMode.Open, IO.FileAccess.Read)
        Dim ser As New Xml.Serialization.XmlSerializer(GetType(ControlsInfo))
        ci = ser.Deserialize(fs)
    End Using
    Me.TextBox1.Text = ci.textbox1text
    Me.RadioButton1.Checked = ci.radiobutton1checked
    Me.RadioButton2.Checked = ci.radiobutton2checked
    Me.SaveButton.Enabled = ci.savebuttonenabled
End Sub
Here's how that Xml looks:
HTML:
<?xml version="1.0"?>
<ControlsInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <textbox1text>1</textbox1text>
  <radiobutton1checked>false</radiobutton1checked>
  <radiobutton2checked>true</radiobutton2checked>
  <savebuttonenabled>true</savebuttonenabled>
</ControlsInfo>
This isn't a very flexible solution and it takes a lot of code, 30 lines just for these 4 info fields.

I have also created an advanced sample, but I'm not sure if it will help you learn. It is a basic StateSaver class that preserves the most common properties of all controls on a form. Keywords is reflection, recursion, TypeDescriptor and TypeConverter - all which are advanced programming topics. The class is just 90 lines of code, see attachment project. As you can see in sample project it is easy to use just calling StateSaver.Save(Me) or StateSaver.Load(Me) in the form to preserve.

Perhaps I will also post an example of custom serialization, which involves implementing Xml.Serialization.IXmlSerializable or Runtime.Serialization.ISerializable interfaces, but I think this will give some more code.
 

Attachments

  • vbnet20-SimpleSaveState.zip
    19.7 KB · Views: 14
though the code was interesting (and unfortunatly, exactly what i feared it would be) i greatly appreciate the given class.
i havent tried it yet, but my only question is will it work with the panel? i dont see why it wouldnt, and im going to try it out, but i wanted to check.

thanks so much for your help
 
so my next question is.. how would i get a certain variable (ie, number of controls) so that i could first add the required number of controls before loading?
 
For example if you have dynamically added controls in code and persisted with the StateSaver class I posted, and they are not there anymore when you decide to load state, then they will not be created because the given code only set properties for an existing named control. It is easy to add code for it to create controls that don't exist, take this part in LoadControl method:
VB.NET:
If c IsNot Nothing Then
    LoadControl(c, cs)
End If
To make it create instances that don't exist just change it to:
VB.NET:
If c Is Nothing Then
    c = Activator.CreateInstance(Type.GetType(cs.TypeName))
    parent.Controls.Add(c)
End If
LoadControl(c, cs)
As you see required here is TypeName, a unique string that identifies the type to create a new instance of. This need to be saved as part of the ControlState, for simplicity add a TypeName field:
VB.NET:
Public TypeName As String
and save it with the rest in constructor (the Sub New(ctl) method):
VB.NET:
Me.TypeName = ctl.GetType.AssemblyQualifiedName
 
Back
Top