Windows Develop Bookmark and Share   
 index > Windows Forms Designer > I don't know how to deserialize multiples objects from a binary file - help!
 

I don't know how to deserialize multiples objects from a binary file - help!

I'm having a trouble. I'm working in an application that allows to the user designs a form at design time (drag controls into a form)... The problem is that a form can't be to serialize. Then, I use a foreach bucle for get all controls in the form.Container.Components collection. Each control is serialized into a file called "myserialize.bin" (using append in the stream). All working until here. I don't know how load or re-create each component (into the "myserialize.bin" file).

How to deserialize the objects (stored in a binary file) and that this files allow in the original state (at design time).?

I need help in this point. Sad


RegardsSmile

Tabas  Tuesday, August 09, 2005 4:37 PM
Hi!

I found the solution to my problem. I don't know if this is the best way, but sincerely, i lost many time with this issue (thanks to my boss for his patience!Sad).

I implemented a PropertyDescriptorCollection for get the properties into the deserialized object and subsequently assign the values into this properties to the component (host.CreateComponent) created with the "design-time" behavior. Using a PropertyDescriptor, you can get/set the value in a property into/from a component. The code below , shows how to get the value (using .GetValue() method) into the property "MargenSuperior" from the object m_qlabelcomponent and set to the same property into the object m_customcomponent (that implements IComponent, IDesignerHost, ISite, etc.; that allow use this component in an design mode environment at run-time:


((QLabel)m_customcomponent).MargenSuperior = (int) props["MargenSuperior"].GetValue(m_qlabelcomponent);
 


See the attached image for more details in the code.



Like you can see in the code, set the Parent property for the component with the RootComponent in the hostdesigner, allow that the control become visible and that have a "design-time" behavior.


/*Get the Parent property*/
propParent = props["Parent"];
/*Set the Parent property to the form:*/
propParent.SetValue(m_customcomponent, host.RootComponent);

 


Codify serialization and deserialization is not easy, and sincerely i was very worried because this issue taken many development time.

Thanks to all coders that indifferently gave to me time, code, tips and support
.Big Smile


Regards

PS. IdeaI hope that this code helps to another members in the forum.

Tabas  Thursday, August 18, 2005 6:25 PM
Here's what I do:

I create a complex datastructure to my liking

Fill the datastructure with whatever.

I create a dictionary(Type Integer, Datastructure) and fill the dictionary

I then serialize the dictionary itself

Deserialization consists of reading the binary file into a new dictionary.


A code example is below:

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters.Binary

Imports System.Windows.Forms

<Serializable()> Public Class clsIO

'Class for serializable IO

<Serializable()> Public Structure psec  ' This is an example of the datastructure

   Dim Image As Image

   Dim Name As String

   Dim FileSpec As String

   Dim CommandModifier As String

   Dim Visible As Boolean

End Structure

   Protected sOriginalDirectory As String = System.Environment.CurrentDirectory

 

Public Structure ImgIndxAndToolTip

   Dim Status As Long

   Dim ImageIndex As String

   Dim Tooltip As String

End Structure

Protected Const cSeparator As String = "Separator"

Public ItemDB As New Dictionary(Of Integer, psec)()

Protected packet As New psec

Protected bSeparator As Boolean


Public
Sub New()

End Sub


Public
Sub LoadMasterDatabase()

'Deserialize and read the Items and Icon databases

   Dim name As String = GetRTMFilename()

   If File.Exists(name) Then

      Dim fsi As New System.IO.FileStream(name, IO.FileMode.Open) ' Open the dictionary in the defaulting directory

   Dim BinFormatter As New BinaryFormatter()

Dim obj As Object

Dim i As Integer

ItemDB.Clear()

Try

obj = BinFormatter.Deserialize(fsi)

ItemDB = (CType(obj, Dictionary(Of Integer, psec)))

Catch e As SystemException

GoTo Common_exit

Finally

fsi.Close()

End Try

For i = 0 To ItemDB.Count - 1

bSeparator = False

packet = ItemDB.Item(i)

FrmToolBar.Pb1.Image = packet.Image

If packet.FileSpec <> cSeparator Then

FrmToolBar.AddNewToolStipButton1(packet.FileSpec, packet.Image)

Else

FrmToolBar.AddSeparator()

End If

Next

End If

Common_exit:

End Sub

Public Sub WriteMasterDatabase()

Dim Outfile As String = GetRTMFilename()

Dim Fso As New System.IO.FileStream(Outfile, IO.FileMode.Create)

Dim i As Integer

Dim btn As New ToolStripButton

ItemDB.Clear()

If FrmToolBar.Toolbar.Items.Count > 0 Then

For i = 0 To FrmToolBar.Toolbar.Items.Count - 1

bSeparator = False

Try

btn = FrmToolBar.Toolbar.Items(i)

Catch

bSeparator = True

packet.Image = Nothing

packet.FileSpec = cSeparator

packet.Name = ""

packet.CommandModifier = ""

End Try

If Not bSeparator Then

FrmToolBar.Pb1.Image = btn.Image

packet.Image = btn.Image

packet.FileSpec = btn.Tag()

packet.Name = btn.Name

packet.Visible = True

End If

ItemDB.Add(ItemDB.Count, packet)

Next

Dim BinFormatter As New BinaryFormatter

Try

BinFormatter.Serialize(Fso, ItemDB)

Finally

Fso.Close()

End Try

End If

 

End Sub

Public Function WriteItemRecord(ByRef RecNum As Integer, ByRef Obj As Object) As Boolean

WriteItemRecord = True

Try

ItemDB.Add(ItemDB.Count, Obj)

Catch

MsgBox("WriteItemRecord Error: " & Err.Description, MsgBoxStyle.OKOnly)

WriteItemRecord = False

End Try

End Function

Public Function ReadItemRecord(ByRef RecNum As Integer, ByRef Packet As psec) As Boolean

ReadItemRecord = True

Try

Packet = ItemDB.Item(RecNum)

Catch

MsgBox("ReadItemRecord Error: " & Err.Description, MsgBoxStyle.OKOnly)

ReadItemRecord = False

End Try

End Function

Public Sub ClearItemDictionary()

ItemDB.Clear()

End Sub

Public Function DoesDBFileExist(ByVal Filename As String) As Boolean

DoesDBFileExist = System.IO.File.Exists(Filename)

End Function

Private Function GetRTMFilename() As String

Const DBSFilePrefix As String = "ToolBar"

GetRTMFilename = sOriginalDirectory & "\" & DBSFilePrefix & ".dbs"

End Function

End Class


ReneeC  Tuesday, August 16, 2005 3:09 PM
Hi ReneeC,

Thanks a lot for your reply.

I have implemented a dictionary into my code (hashtable) and all works fine (serialization and deserialization). When I serialize the dictionary, all objects into it are serialized fine. When I deserialize the object (hashtable) no error is fired.  See attached image, in this image the object is showed with all properties with the values that the user sets.




The problem is that i need that the objects become restored in design mode, the user must be able of modify the design, but all code implements for me not works. The objects must be placed into a IDesignerHost (a form) at run-time, but they are placed but i cant see the objects!. I need the deserialized objects at run-time and that the objects have the desing-time behavior (like they were, previous the serialization process), into this hostdesigner.


See the code for serialize and deserialize the object (sorry, the code is in c#):

http://rapidshare.de/files/4085573/Hosting.zip.html


Regards
Tabas  Wednesday, August 17, 2005 5:25 PM
Hi Tabas,

I'm really elated you could receive some benefit from what I suggested. I find that creating a dictionary of a complex datastructure, loading the dictionary and serializing and deserializing them to be very hardy and a wonderful and dynamic way to deal with serialization. I've even had great success with serializing multiple dictionaries in the same binary file. All you have to do is to respect the order in which you do it.

I am not a .Net Guru. As with all my many years of computer experience, I am self trained. I did have some questions as well as thoughts about your last post and I need to have them answered in order to insure that we are on the same page.

You speak of "designer mode". Would I be correct that what you are referring to is a very dynamic application, an exectuable image running in a particular mode? It's running a particular class (?) and possibly it's a restrictive class to support the dynamism?

If these assumptions are correct... does this class prevent you from referencing other classes? If not, it seems to me that you could do your serialization and deserialization in those classes and bring them into the designer class?

I apologize for being so dense but I'm not familiar with the restrictions of the class to which you are referring. Perhaps you could educate me so I might be so fortunate as to come up with some suggestions?




ReneeC  Thursday, August 18, 2005 3:51 AM
@ReneeC,

Thank You a ot for your support.

Ok. I'm developing an application that allows to the user to design id cards. The application have a toolbar that contain all objects (classes) that the user can use for a id card design (e.x., photo, label, textbox, barcode, sign area, chip area, etc.). All this objects must have the behavior that a control has when is placed in a form at design-mode (into the IDE). I need that this controls remain or become placed into the desing area like if this objects are in a design mode (but my application is running), this main that... all objects must be able of change the size, move to another place, change its attributes, etc. Prior of the serialization process, this objects had this behavior.

IOW, my application allows to the user at run-time, works this objects like a developer do it at design-time into the NET2003's IDE.

The problem is that the rootdesigner is not placed for the object. But i can't to serialize a form (like an ISite).

Regards

Tabas  Thursday, August 18, 2005 2:16 PM
Hi!

I found the solution to my problem. I don't know if this is the best way, but sincerely, i lost many time with this issue (thanks to my boss for his patience!Sad).

I implemented a PropertyDescriptorCollection for get the properties into the deserialized object and subsequently assign the values into this properties to the component (host.CreateComponent) created with the "design-time" behavior. Using a PropertyDescriptor, you can get/set the value in a property into/from a component. The code below , shows how to get the value (using .GetValue() method) into the property "MargenSuperior" from the object m_qlabelcomponent and set to the same property into the object m_customcomponent (that implements IComponent, IDesignerHost, ISite, etc.; that allow use this component in an design mode environment at run-time:


((QLabel)m_customcomponent).MargenSuperior = (int) props["MargenSuperior"].GetValue(m_qlabelcomponent);
 


See the attached image for more details in the code.



Like you can see in the code, set the Parent property for the component with the RootComponent in the hostdesigner, allow that the control become visible and that have a "design-time" behavior.


/*Get the Parent property*/
propParent = props["Parent"];
/*Set the Parent property to the form:*/
propParent.SetValue(m_customcomponent, host.RootComponent);

 


Codify serialization and deserialization is not easy, and sincerely i was very worried because this issue taken many development time.

Thanks to all coders that indifferently gave to me time, code, tips and support
.Big Smile


Regards

PS. IdeaI hope that this code helps to another members in the forum.

Tabas  Thursday, August 18, 2005 6:25 PM

You can use google to search for other answers

Custom Search

More Threads

• Designer for developing report templates
• Inherited UserControl - how to change base controls?
• The type or namespace name IDump,TextProperty,RemoteFilePathProperty,SourceFileproperty,TransferPorotocolProperty,ValidityCheck,DestinationFileProperty could not be found (are you missing a using directive or an assembly
• Background of the selected text ?
• Exposing UserControl collections at design time
• Supporting 2003 & 2005 InitializeComponent
• CommandText Property Editor
• Runtime resize handles
• Split Container
• How to create an instance of System.Windows.Forms.AxHost.State ?