Click here to Skip to main content
14,032,238 members
Click here to Skip to main content
Add your own
alternative version


6 bookmarked
Posted 17 Apr 2008
Licenced CPOL

ComplexConverter - make configuration still more flexible

, 17 Apr 2008
Rate this:
Please Sign up or sign in to vote.
Converting complex Object-structures to string and reverse. Storing the result in an application-setting improves configurations flexibility substantially
Download ComplexConverter_src - 18.74 KB


What I'd like to share is a technique, how multiple data items can be collected and converted into one String. The String can be stored as an application-setting, and all the data can be restored from it by one call.
This is useful to persist arbitrary user-settings, Form-Bounds, Form-WindowState, Widths of Splitterpanels, Slider-Positions, Widths of Columnheaders and stuff like this.
Actually a complete Treeview can be made persistent, with each Treenodes .Text, .IsExpanded-Property or what else may be important to save.

Using the code

Storing or Restoring starts with the call

(Dim S As String)  
S = aComplexConverter.ConvertToString() 
Both calls will raise the same aComplexConverter.Convert() - event, where the user has to implement a pass-through through his data and "point out" each Item he wants to get stored/restored.

Here a sample for a complex storing:

It stores/restores two Form-Properties (WindowState, Bounds), a Treeview (each TreeNode.Text, TreeNode.IsExpanded), the current Column-Widths of a ListView and all its Items (each SubItems Text)
Private WithEvents _Memory As New ComplexConverter

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
        Handles MyBase.Load
End Sub

Private Sub Form1_FormClosing( _
        ByVal sender As Object, ByVal e As FormClosingEventArgs) _
        Handles Me.FormClosing
    My.Settings.Memory = _Memory.ConvertToString()
End Sub

'''<span class="code-SummaryComment"><summary>complex conversion for this form</summary></span>
Private Sub _Memory_Convert( _
        ByVal sender As Object, ByVal e As ComplexConverter.EventArg) _
        Handles _Memory.Convert
    'convert Form-Properties
    With Me
    End With
    'convert Treeview
    EnumerateNodes(TreeView1.Nodes, e)
    'convert ListViews Column-Withs
    For Each Col As ColumnHeader In Me.ListView1.Columns
    'convert ListView-Items
    e.ConvertList(Of ListViewItem)(ListView1.Items)
    For Each LVI As ListViewItem In ListView1.Items
        'convert ListView-SubItems
        e.ConvertList(Of ListViewItem.ListViewSubItem)(LVI.SubItems)
        For Each SITM As ListViewItem.ListViewSubItem In LVI.SubItems
End Sub

Private Sub EnumerateNodes( _
        ByVal Nodes As TreeNodeCollection, ByVal e As ComplexConverter.EventArg)
    e.ConvertList(Of TreeNode)(Nodes)
    For Each Nd As TreeNode In Nodes
        EnumerateNodes(Nd.Nodes, e)
        'Workaround: Treenode.IsExpanded is readonly, so I can't restore it directly
        Dim B As Boolean = Nd.IsExpanded
        If B Then Nd.Expand()
End Sub

Two types of data have to be distinguished: Values and Lists. Values are stored/restored as they are, their datatype is inferred by the generic ConvertValue(Of T)(ByRef Item As T)-method.


Lists are stored by only saving their .Count. They are restored by generating and adding Count unititialized items.
For that the "pointing out" of any type of List requires to pass the datatype of its Items by Type-Parameter to the
ConvertList(Of TItem As New)(ByVal List As IList)-method.

'convert ListView-Items
e.ConvertList(Of ListViewItem)(ListView1.Items)

Points of Interest

The hack in this is: the same code is used for storing and also for restoring. This has two positive effects:

  • The user defines the conversion for both directions in only one data-pass-through-code.
  • Only pure data needs to be stored. No additional information, about what type of data, in which order it occurs, or how to interpret (like e.g. Xml-Serialisation would do).
These additionals need not to be stored, but stay immanently in the handler-code of the Convert-event. So the stored string is very compact - e.g. a result of the above shown code-sample:
Normal|0; 0; 765; 321|2|Knoten0|2|Knoten1|0|False|Knoten2|3|Knoten4|0|False|Knoten5|0|False|Knoten6|0|

Inside ComplexConverter

ComplexConverter has a problem, when set up, or conversion-code is changed. After a change it will read the old data, which doesn't fit no more.
For that RestoreFromString() raises the Convert-Event two times in two different modes: TryRestore-mode and Restore-mode
TryRestore imitates a restoring, but writes the values into a buffer. If an error occurs, the exception is catched and the restoring-process will be aborted without writing data to any target-property. So the targets will stay in their default-configuration.
Finally in the Restore-mode the data will be copied to the target-properties.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Germany Germany
No Biography provided

You may also be interested in...


Comments and Discussions

Generalhum Pin
konikula6-Jan-10 21:05
memberkonikula6-Jan-10 21:05 
GeneralRe: hum Pin
Mr.PoorEnglish25-Feb-10 23:12
memberMr.PoorEnglish25-Feb-10 23:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190419.4 | Last Updated 17 Apr 2008
Article Copyright 2008 by Mr.PoorEnglish
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid