-
1 Attachment(s)
[2005]Saving/Loading a forms layout.
Here's a class I wrote a while ago that uses binary serialization and reflection to serialize all the serializable properties of a form and its child controls to a given stream, this can be any type of stream, such as a filestream or a networkstream.
It can deserialize from a given stream and apply the property values directly to a form (and the child controls).
Personally I havent had any use of it but I figured someone might find it interesting...I'll attach it to this post.
The loading can be sluggish if there are alot of data to read in, altough I am working on making the LoadLayout method asynchronous.
I havent commented the code in any way unfortunately, so dont hesitate to ask if something looks strange.
Feel free to comment. :D
EDIT: Using the class is pretty straight forward, but I figured I'd add an example:
To save the forms layout to a file, create a filestream and pass it + the form instance to the SaveLayout method:
The SaveLayout and LoadLayout methods are both shared so you dont need to create a new instance of the class in order to use them.
VB.Net Code:
Dim fs As New IO.FileStream("c:\layout.bin", IO.FileMode.Create)
LayoutSerializer.SaveLayout(Me, fs)
fs.Close()
And here's how you'd load it again:
VB.Net Code:
Dim fs As New IO.FileStream("c:\layout.bin", IO.FileMode.Open)
LayoutSerializer.LoadLayout(Me, fs, LayoutSerializer.LoadMode.DontCreateExistingControls)
fs.Close()
Note that I've specified "DontCreateExistingControls" in the LoadLayout call..
This means that controls that already exist on the form should not be created again, but its property values will still be overwritten with the property values from the loaded layout.
There are two more LoadMode enums, I think you understand what they do by looking at their names.
-
Re: [2005]Saving/Loading a forms layout.
Quote:
Originally Posted by Atheist
I am working on making the LoadLayout method asynchronous.
I'm very interested in this. Would you have the async code ?
-
Re: [2005]Saving/Loading a forms layout.
Hey there.
No I ran into some strange crossthreading issue and put it aside, but if you need it I could pick it up again and try to get it finished.
-
Re: [2005]Saving/Loading a forms layout.
Also, using the latest discovery of mine (see my last codebank submission), I'll try to see if i can retain the eventhandlers for the controls events after serialization/deserialization.
-
Re: [2005]Saving/Loading a forms layout.
Cool. I'd love to see it and hope you can get the async kicking.
-
Re: [2005]Saving/Loading a forms layout.
I'll begin tomorrow, I need my beauty sleep now. ;)
-
Re: [2005]Saving/Loading a forms layout.
-
Re: [2005]Saving/Loading a forms layout.
Im currently working on it, serializing information about the eventhandlers wasnt as easy as I thought, my first attempt was to immediately serialize the Delegate object that represents the EventHandler for each event, but the problem is that the eventhandler has a property called Target that references the object whos event it is handling, it will try to serialize that object aswell, which wont work well as most (all?) controls arent serializable.
My second immediate thought was to just serialize the delegate information as a System.Reflection.MethodInfo object, this works well...but upon deserializing i must reconstruct a delegate using this MethodInfo object and this is where I am at the moment...but I think I'll figure it out soon.
I figured I wont start with the asynchronous methods until the synchronous methods are 100% complete.
-
Re: [2005]Saving/Loading a forms layout.
No rush bro, just giving you a thumbs up.
-
Re: [2005]Saving/Loading a forms layout.
Why not append the layout settings to the end of the exe file and get the exe to read itself and change the layout when it starts up?
-
Re: [2005]Saving/Loading a forms layout.
Atheist:
I am trying to use the LayoutSerializer but I am having an issue with it. On line 79 of the Serializer in the ControlInfo Class I keep getting a ArgumentException was unhandled error. That reads "An item with the same key has already been added."
It appears it has something to do with adding a value with the key name of "Padding" because the key already exists.
Not quite sure how to fix this.
Thanks.
-
Re: [2005]Saving/Loading a forms layout.
Hey there. What type of control does this error occur on? I'll try to recreate the error.
-
Re: [2005]Saving/Loading a forms layout.
Quote:
Originally Posted by Atheist
Hey there. What type of control does this error occur on? I'll try to recreate the error.
It appears to be a tab control. I have 4 tabs on it.
Thanks again.
-
Re: [2005]Saving/Loading a forms layout.
I get an error on
Code:
Private Class ControlInfo
Public ControlType As Type
Public Properties As New Dictionary(Of String, Object)
Sub New(ByVal ctrl As Control)
ControlType = ctrl.GetType
Dim value As Object
For Each pi As Reflection.PropertyInfo In ControlType.GetProperties
If pi.CanWrite Then
----------->>>>> value = pi.GetValue(ctrl, Nothing)
If value Is Nothing OrElse value.GetType.IsSerializable Then
Properties.Add(pi.Name, value)
End If
End If
Next
End Sub
End Class
Description is "Exception has been thrown by the target of an invocation."
when I try to apply
Code:
Dim fs As New IO.FileStream("c:\layout.bin", IO.FileMode.Create)
LayoutSerializer.SaveLayout(Me, fs)
fs.Close()
on my form closed event...
-
Re: [2005]Saving/Loading a forms layout.
Quote:
Originally Posted by
wenight
I get an error on
Code:
Private Class ControlInfo
Public ControlType As Type
Public Properties As New Dictionary(Of String, Object)
Sub New(ByVal ctrl As Control)
ControlType = ctrl.GetType
Dim value As Object
For Each pi As Reflection.PropertyInfo In ControlType.GetProperties
If pi.CanWrite Then
----------->>>>> value = pi.GetValue(ctrl, Nothing)
If value Is Nothing OrElse value.GetType.IsSerializable Then
Properties.Add(pi.Name, value)
End If
End If
Next
End Sub
End Class
Description is "Exception has been thrown by the target of an invocation."
when I try to apply
Code:
Dim fs As New IO.FileStream("c:\layout.bin", IO.FileMode.Create)
LayoutSerializer.SaveLayout(Me, fs)
fs.Close()
on my form closed event...
it only appear the error when my form contain listview, dataGridView....
any solution to solve it??
-
Re: [2005]Saving/Loading a forms layout.
Do you know what property it is trying to get the value from when this is happening?
-
Re: [2005]Saving/Loading a forms layout.
I don't know what the value it get when happening...
How to prevent unnecessary property to store??
Something like
Code:
If control= "Textbox" Then
If property <> "Text" Then
store to binary...
End if
Else If control = "Label" Then
If property <> "Text" Then
store to binary...
End If
Else if control = "ListView" Then
If property <> "Item" or property <> "Column" Then
store to binary...
End If
Else if control = "Checkbox" Then
If property <> "Checked" Then
store to binary...
End If
End if
-
Re: [2005]Saving/Loading a forms layout.
I like your class very much; it is so easy to save and load a Form's layout! Thanks. :wave:
Though, I typed something in a Textbox and used your class to save it, but when loading it, the Textbox didn't have that text, or does your code not pretend to do so?
-
Re: [2005]Saving/Loading a forms layout.
Hi, the control work fine for me now, the only problem is children control like groupbox and tabcontrol will be duplicate.
can it be solve?
I think the function when save the layout it did not save the parent property or when load the layout it no load the parent property
-
Re: [2005]Saving/Loading a forms layout.
Hey Atheist,
I tested out your code on a blank project and it worked great.
I then added it to one of my project and received an error on line 43,
VB.NET Code:
ci.ControlType.GetProperty(dictEntry.Key).SetValue(ctrl, dictEntry.Value, Nothing)
The error is below:
Quote:
System.Reflection.TargetInvocationException was unhandled Message="Exception has been thrown by the target of an invocation." Source="mscorlib"
So, since a blank project worked fine and the error seem to target the ControlType, I started another blank project with all of the same controls. I have some custom made controls and thought that was the issue to begin with.
With the process of elimination, I determined that the error was caused because of a ToolStrip. Imagine that.
Any idea why this is happening?
-
Re: [2005]Saving/Loading a forms layout.
-
Re: [2005]Saving/Loading a forms layout.
Is this really of any use to anyone? If so, in what context are you using it?
Looking back at this submission of mine, I almost wish I could remove it from the codebank as its just plain worthless :)
-
Re: [2005]Saving/Loading a forms layout.
Quote:
Originally Posted by
Atheist
Is this really of any use to anyone? If so, in what context are you using it?
Looking back at this submission of mine, I almost wish I could remove it from the codebank as its just plain worthless :)
It's not worthless. In fact, I love it. I'm having some trouble getting it to work with the ToolStrip mentioned above and some custom controls I made, but other than that, I love the idea.
I'm currently working on a project that requires my 'designer' to be saved. It's kind of the same fashion that we use in VS. And something like this would make my life so much easier.
The problem I have with my custom controls, is that everything appears to save and load, but when the custom controls load, they're text do not. They're custom labels inside of a custom panel =/