|
-
Aug 22nd, 2018, 08:16 AM
#1
Thread Starter
Lively Member
[RESOLVED] Serialization of a Windows Form State - Help to refine the code
Hello
At this time, in a code to save information, there is no software that you are creating.
First: the application has a series of windows, where the user types and strings. So in the end, I do not need a database to save everything, because it's not much to save. I've chosen to use the serialization method, saving everything to an .xml file.
But like every beginner, I have some doubts:
1) In my software, the various windows, which perform codepentes activities, the result of one and used in the following. And it is not a process with some calculations, and it turns out that I intend to generate a final report.
Returning to the serialization, I have how to save data from all forms to a single .xml file? Or do I need to generate a file for each form?
2) Second question: When the user clicks save, how can I provide the option for him to choose where he wants to save the project .xml file? Even when he returns to complete the work he has saved, can I open a window for him to get the .xml file he saved?
Currently I'm following the following serialization structure:
I created a class called "Serialize.vb" (Serialise, in portuguese)
Code:
Imports System
Imports System.IO
Imports System.Windows.Forms
Imports System.Reflection
Imports System.Xml
Imports System.Diagnostics
Public Class Serializar
Public Sub New()
End Sub
Public Shared Sub Serialise(ByVal c As Control, ByVal XmlFileName As String)
Dim xmlSerialisedForm As XmlTextWriter = New XmlTextWriter(XmlFileName, System.Text.Encoding.[Default])
xmlSerialisedForm.Formatting = Formatting.Indented
xmlSerialisedForm.WriteStartDocument()
xmlSerialisedForm.WriteStartElement("ChildForm")
AddChildControls(xmlSerialisedForm, c)
xmlSerialisedForm.WriteEndElement()
xmlSerialisedForm.WriteEndDocument()
xmlSerialisedForm.Flush()
xmlSerialisedForm.Close()
End Sub
Private Shared Sub AddChildControls(ByVal xmlSerialisedForm As XmlTextWriter, ByVal c As Control)
For Each childCtrl As Control In c.Controls
If Not (TypeOf childCtrl Is Label) Then
xmlSerialisedForm.WriteStartElement("Control")
xmlSerialisedForm.WriteAttributeString("Type", childCtrl.[GetType]().ToString())
xmlSerialisedForm.WriteAttributeString("Name", childCtrl.Name)
If TypeOf childCtrl Is TextBox Then
xmlSerialisedForm.WriteElementString("Text", (CType(childCtrl, TextBox)).Text)
ElseIf TypeOf childCtrl Is Label Then
xmlSerialisedForm.WriteElementString("Text", (CType(childCtrl, Label)).Text)
ElseIf TypeOf childCtrl Is ComboBox Then
xmlSerialisedForm.WriteElementString("Text", (CType(childCtrl, ComboBox)).Text)
xmlSerialisedForm.WriteElementString("SelectedIndex", (CType(childCtrl, ComboBox)).SelectedIndex.ToString())
ElseIf TypeOf childCtrl Is ListBox Then
Dim lst As ListBox = CType(childCtrl, ListBox)
If lst.SelectedIndex = -1 Then
xmlSerialisedForm.WriteElementString("SelectedIndex", "-1")
Else
For i As Integer = 0 To lst.SelectedIndices.Count - 1
xmlSerialisedForm.WriteElementString("SelectedIndex", (lst.SelectedIndices(i).ToString()))
Next
End If
ElseIf TypeOf childCtrl Is CheckBox Then
xmlSerialisedForm.WriteElementString("Checked", (CType(childCtrl, CheckBox)).Checked.ToString())
ElseIf TypeOf childCtrl Is RadioButton Then
xmlSerialisedForm.WriteElementString("Checked", (CType(childCtrl, RadioButton)).Checked.ToString())
ElseIf TypeOf childCtrl Is Button Then
xmlSerialisedForm.WriteElementString("Enabled", (CType(childCtrl, Button)).Enabled.ToString())
End If
Dim visible As Boolean = CBool(GetType(Control).GetMethod("GetState", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(childCtrl, New Object() {2}))
xmlSerialisedForm.WriteElementString("Visible", visible.ToString())
If childCtrl.HasChildren Then
If TypeOf childCtrl Is SplitContainer Then
AddChildControls(xmlSerialisedForm, (CType(childCtrl, SplitContainer)).Panel1)
AddChildControls(xmlSerialisedForm, (CType(childCtrl, SplitContainer)).Panel2)
Else
AddChildControls(xmlSerialisedForm, childCtrl)
End If
End If
xmlSerialisedForm.WriteEndElement()
End If
Next
End Sub
Public Shared Sub Deserialise(ByVal c As Control, ByVal XmlFileName As String)
If File.Exists(XmlFileName) Then
Dim xmlSerialisedForm As XmlDocument = New XmlDocument()
xmlSerialisedForm.Load(XmlFileName)
Dim topLevel As XmlNode = xmlSerialisedForm.ChildNodes(1)
For Each n As XmlNode In topLevel.ChildNodes
SetControlProperties(CType(c, Control), n)
Next
End If
End Sub
Private Shared Sub SetControlProperties(ByVal currentCtrl As Control, ByVal n As XmlNode)
Dim controlName As String = n.Attributes("Name").Value
Dim controlType As String = n.Attributes("Type").Value
Dim ctrl As Control() = currentCtrl.Controls.Find(controlName, True)
If ctrl.Length = 0 Then
Else
Dim ctrlToSet As Control = GetImmediateChildControl(ctrl, currentCtrl)
If ctrlToSet IsNot Nothing Then
If ctrlToSet.[GetType]().ToString() = controlType Then
Select Case controlType
Case "System.Windows.Forms.TextBox"
CType(ctrlToSet, System.Windows.Forms.TextBox).Text = n("Text").InnerText
Case "System.Windows.Forms.Label"
CType(ctrlToSet, System.Windows.Forms.Label).Text = n("Text").InnerText
Case "System.Windows.Forms.ComboBox"
CType(ctrlToSet, System.Windows.Forms.ComboBox).Text = n("Text").InnerText
CType(ctrlToSet, System.Windows.Forms.ComboBox).SelectedIndex = Convert.ToInt32(n("SelectedIndex").InnerText)
Case "System.Windows.Forms.ListBox"
Dim lst As ListBox = CType(ctrlToSet, ListBox)
Dim xnlSelectedIndex As XmlNodeList = n.SelectNodes("SelectedIndex")
For i As Integer = 0 To xnlSelectedIndex.Count - 1
lst.SelectedIndex = Convert.ToInt32(xnlSelectedIndex(i).InnerText)
Next
Case "System.Windows.Forms.CheckBox"
CType(ctrlToSet, System.Windows.Forms.CheckBox).Checked = Convert.ToBoolean(n("Checked").InnerText)
End Select
ctrlToSet.Visible = Convert.ToBoolean(n("Visible").InnerText)
If n.HasChildNodes AndAlso ctrlToSet.HasChildren Then
Dim xnlControls As XmlNodeList = n.SelectNodes("Control")
For Each n2 As XmlNode In xnlControls
SetControlProperties(ctrlToSet, n2)
Next
End If
Else
End If
Else
End If
End If
End Sub
Private Shared Function GetImmediateChildControl(ByVal ctrl As Control(), ByVal currentCtrl As Control) As Control
Dim c As Control = Nothing
For i As Integer = 0 To ctrl.Length - 1
If (ctrl(i).Parent.Name = currentCtrl.Name) OrElse (TypeOf currentCtrl Is SplitContainer AndAlso ctrl(i).Parent.Parent.Name = currentCtrl.Name) Then
c = ctrl(i)
Exit For
End If
Next
Return c
End Function
End Class
Then in the WindowsForm, I call the serialization when the user clicks in the button Save:
Code:
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Serializar.Serialise(Me, Application.StartupPath + "\side_predimensionamento.xml")
End Sub
And open the file when the user clicks in the button Open
Code:
Private Sub btnOpen_Click(sender As Object, e As EventArgs) Handles btnOpen.Click
Serializar.Deserialise(Me, Application.StartupPath + "\side_predimensionamento.xml")
End Sub
Use this article to obtain this method of serialization. I've converted from C # to VB.NET, which I'm using. https://www.codeproject.com/Articles...a-Windows-Form
A appreciate all help.
Thanks
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|