Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Advanced WPF TreeViews in C#/VB.Net Part 5 of n

0.00/5 (No votes)
18 Jan 2018 6  
Tips & Tricks on de/serializing Tree View based content with XML

Introduction

This article shows how the content of a WPF/MVVM TreeView can be saved and re-loaded with XML.

Background

A recent article [5] on Reading and Writing XML in C#/VB.Net discussed different options for using XML in .Net. This article builds on this base and gives a practical example with a demo application that is similar to the Solution Explorer Tool Window in Visual Studio.

Using the code

You should be able to just download the attached sample, open the project in VS 2017 Community, restore nuget packages, compile, and run (use the Forum below, if you have any questions).

The following screenshot shows the main window of the demo application:

Sample Screenshot

You can use the context menu (see above) to arrange the items in the tree view. Use the Save button (see below) to save the content of the tree view.

Sample Screenshot

The application shows a standard Save dialog that contains 2 file pattern options:

  • *.solxml
  • *.solsqlite

Choose the *.solsqlite option, if you prefer a binary relational data format as discussed in [4]. Choose the *.solxml option, if you want to save and load the contents of the tree view in good old plain XML.

Sample Screenshot

Reloading data is implemented with the same workflow but using the Load button.

The sequence diagram below shows the workflow between the main objects participating in the interaction for saving the XML data:

The button click in MainWindow.xaml invokes the bound ICommand SaveSolutionCommand property in the AppViewModel class, which in turn displays the standard file save dialog to let the user choose a file name, location, and the format.

The AppViewModel.Save_SolutionCommand_Async() method then converts the viewmodel into a model as previously discussed for saving in the SQLite data format [4]:

The resulting tree model (shown above) is composed out of internal classes only. That is, everyone outside of the SolutionLibModels library can only use the associated interfaces and the Factroy class to interact with these data items.

The converted model is then handed over to the SolutionLibModels.Xml.Storage.WriteXmlToFile() method that implements the actual serialization via DataContractSerializer and IXmlSerializable interface:

public static void WriteXmlToFile(string filename, ISolutionModel rootModel)
{
  XmlWriter xmlWriter = null;
  try
  {
    var fileStream = new FileStream(filename, FileMode.Create);
    xmlWriter = XmlWriter.Create(fileStream, new XmlWriterSettings
    {
        Indent = true,
        IndentChars = "  ",
        CloseOutput = true
    });

    var dataContractSerializer = new DataContractSerializer(typeof(SolutionModel));
    dataContractSerializer.WriteObject(xmlWriter, rootModel);
  }
  finally
  {
    if (xmlWriter != null)
        xmlWriter.Close();
  }
}

The WriteXmlToFile() method is pretty much the same method that we have previously used to load and save XML [5] as shown in the DataContractSerializer_V1.zip sample. The above code in the Storage class evaluates the ModelRoot and sees the IXmlSerializable interface. So, the DataContractSerializer invoces the ModelRoot.WriteXml() method and this invocations processes' all other ...WriteXml() methods of all other tree view items, if they are processed as previously discussed [5].

The result of the invocation of all the IXmlSerializable methods is hopefully an XML file that should be loadable upon a click on the Load button.

The processing for the loading of the XML Data is very similar - so I leave the explicit explanation out of here.

Conclusions

The above sample also shows an interesting reason for the seemingly additional (useless) burden of having to convert between viewmodel and models. We note that the attached implementation does not have a direct reference from the viewmodel to an XML serializer and/or SQLite storage solution. These references are only visible on the library that implements the model. We can. thus, claim that the model/viemodel conversion ensure a separation of concerns, which in turm will ensure a healthy and simplified development of this code.

Thats it. This is pretty much what I wanted to say about loading and saving WPF tree view content via XML. The sample presented in this article implements the lessons learned from [5], so you should at least read the section about the DataContractSerializer_V1.zip sample in order to understand how the IXmlSerializable interface works here (if you got lost). Otherwise, you are always welcome to leave feedback and ask questions if you feel like something important is missing or plain wrong.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here