Click here to Skip to main content
11,642,613 members (63,073 online)
Click here to Skip to main content

ComplexConverter - make configuration still more flexible

, 17 Apr 2008 CPOL 9.5K 30 6
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    Rant Rant    Admin Admin   

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150731.1 | Last Updated 17 Apr 2008
Article Copyright 2008 by Mr.PoorEnglish
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid