Introduction

As serializing of a TreeNode object does not work as it is said in the Microsoft’s online page, or other Web pages, e.g. Object Serialization using C# on this Web site.

If you try to write a class inherited from a TreeNode object, you will find a NullPointerException during serialization to/from the file. Your process crashes, and a wonderful and beautiful NullPointerException is shown (if you've not caught it).

The reason is one, simple and not easy to reach: the TreeNode object implements the ISerializable interface but deserialization does not work very well, that's because you cannot simply serialize an object that inherits the TreeNode and be able to [Serialize] it.

You can find an example of the problem here. I did not write that code, but it's a great example, and in this article you can find how to resolve it.

Don't worry, there is a SIMPLE and EASY solution, but it would be easier if [Serialize] tag worked as it was supposed to (like Java). I think it's not necessarily a full project to show how it can be done, it's really very simple!

Background

I surfed the Internet, spending a lot of hours trying to find the answer for this problem in C#. Don’t worry, it does not exist anywhere but here. I found some objects that used TreeNode and TreeView as a base class, and derived it (and you had to derive that derived class, not very practical). I suggest that you inherit the TreeNode class, because the TreeView class is used only for GUI approaches (I must say it: use the Facade pattern, very easy and useful while using a memory-GUI duet).

But it was not what I wanted, and it was a lot of work to change my project, and mapping all my work to store it in an XML (so cool, so fantastic, …) but I wanted binary files.

What I wanted was to derive a TreeNode, and store it to a binary or XML file, does not matter what the structure of my object was. At Microsoft's Web page was no answer, I tried to find it. And I won.

Using the Code

After a long time, I found the answer: you can derive your class from TreeNode, but the serializing way works different from other classes (not to say Microsoft’s help). This is how I did it:

Share

About the Author

Young and handsome code-writer, born and living in Spain, left the SW developer job to a very wonderful life of teaching other how to waste your life in front of a 20" machine.
I don't like to write code for other, but code & programs that I write for me, that's great!

Comments and Discussions

OMG; Thank you very much, as you said, there is no info on the microsoft website. it took me hours to find this. thank you very much. all i was missing was how to override the serialization. and it was as easy as overriding serialize. i was trying to override GetObjectData since i am trying to serialize to put it on the clipboard. everything worked fine

Victor, thanks a lot for this article, it has helped me a lot to understand serialization!

One question - have you got success with XML serialization of TreeNode?
Even if there is not a derived class, XML serialization does not work for TreeNode ( I have got an exception that serialization fails on "Context Menu" field, I suppose because this field is read-only, what is not supported by XML serialization).

I have got an idea - try to serialize my class derived from TreeNode, without call of base.Serialize(si, context), but in adding to Serialize() of my derived class serialization and restoring of some chosen properties of TreeNode, but I'm not sure yet that it is not too complicated and that it will work...

I'm not absolutely certain, but I assume you're referring to a WinForms TreeNode, right? I'm going to assume that for the rest of this comment.

In either case, I don't think you can XML-serialize it. TreeNode is binary serializable and implements ISerializable to override the default binary serialization behavior, but it doesn't look like that's what you're after - avoiding some potential default serialization problems in the process, but it does not implement IXmlSerializable and so attempts to create an XmlSerializer instance based on TreeNode (or subtypes) will use the default serialization which, as you pointed out, chokes on the ContextMenu - actually, that's not the only type in the hierarchy that would doom the serialization, as there is no custom XML Serialization attribute decoration to be found in the type. It just doesn't look like it was intended to be serialized to XML.

Do you want the XML to use in a configuration file or something? If so, then you're probably going to have to roll your own export routine. In fact, it kind of looks like you'd be stuck doing that, anyway, if you only want part of your instance to serialize. Since you don't have source for the TreeNode type, you would be unable to control its XML serialization even if it was capable of doing it.

Are you actually using the TreeNode subclass(es) in a TreeView, or are you using TreeNode instances to logically group sets of objects for some other purpose? If it's the latter, you'd be better off just implementing your own collections - that way you could control their serializability.

Hi!
I absolutely agree with you, and that is a good code for serializing a TreeNode, but what happens if you want to serialize another type of object that inherits TreeNode.
As I said before, in the page of Microsoft was said that some extra work was needed, but not how to do that work, and it's costed a lot of my time to find this solution.
Well, I found the solution with XML+WPF+XAML+HierarchicalDataTemplate. I'll prepare a full set of articles covering all that.
And yes, it was about TreeNode for Winforms.
Thanks for your work.

"
Due to the Serialize of a TreeNode object does not work as it is said in the Microsoft’s online page
"

I just checked the help for TreeNode and I see:

"
Notes to Inheritors Because the TreeNode class implements the ISerializable interface, derived classes intended to be serializable must also implement this interface and special constructors as described in Custom Serialization.
"

So clearly the developer has to do some work to serialize derived TreeNodes, are you saying that Serialize doesn't work for standard TreeNodes either?

If you don't believe me, just try it. You'll find that serialization (works) and deseralization (does not work, NullPointerException) does not work as docs said.
I did not try to saving-unsaving the standard TreeNode, I needed some more stuff 4 my program.

And I will better than others and won't try and insult other by using one language or other. It's so simple, while one language has some better features, the other is worst in that features but improves other. For example, I dont have with C# the flexibility in generics I use in Java, and the control-layouts can be REALLY improved in C#. But it is very good in the way there not exists the bean concept (horrible idea). They are just different, and used in very different ways.

Yes, but the documentation tells you that you need to do some work so I don't see what you're complaining about. Actually I don't see why TreeNode implements ISerializable anyway; it seems like a bad design. Like serializing a DataGridView rather than the DataSet that it displays.

Sorry, but you're wrong. The visual control for treenode is TreeView: the TreeNode is the memory representation of TreeView control. And usually you need to serialize a TreeNode inherited object into a binary or xml file. If not, what do you thing about the existence of this DLL (the programmer wanted to waste a lot of time?):http://www.codeproject.com/KB/recipes/phSharpTree.aspx[^]

there is also the explanation why by implementing the ISerializable interface does not works as well.

I wanted only to say that there exists (and I found) a way to make that in a very simple manner (not implementing nor overlying my code: I don't want to work a lot if I can do that smaller), but I'm thinking to delete it: I only found that people don't try to program it and crashes, I only found that people criticizes me 'cos I say that the TreeNode object does not works as it should.

A TreeNode is one item in a TreeView, just as a DataGridViewRow is one item in a DataGridView, neither should be serialized; if anything, you should serialize the data that the TreeNode represents, not the TreeNode itself.

In essence, a TreeNode contains only a string -- and a font and color and such, also a Tag object which may not be Serializable either -- and a string isn't very interesting.

I may have a TreeView that is displaying sports teams. I query a database and populate a DataSet.
Then I populate a TreeView. Some entries contain players' names, in the DataSet I have the first name and last name separate, but in the TreeName they have to be concatenated. Why would I ever choose to serialize the concatenated string rather than the DataRow? There may also be data that needs to be serialized but not displayed.

It would severely limit the flexibility of the design. Let's say I use different colors to indicate some attribute of some players. I could serialize the color of the node, but serializing the attribute is more flexible; I could change the app to use a different color, or allow the user to select a different color, or change to a different control entirely. (I do, in fact, allow users to select their own color scheme and font.)

But I just don't see why you would need to serialize a TreeView in the first place.
What purpose does it serve better than simply serializing the underlying data?

Mmmm, I don't think so. I think that TreeNode is a memory representation for the TreeView, and the most important thing in your treenode object (when you inherits it) is the TREE STRUCTURE inside it (it does not exists in the framework but there). And when you serialize the MyObject:TreeNode object, you are not serializing the TreeView, it's made on the fly.
I used this object to use the tree structure, not the Name string (it's not very useful to me) and to send THE STRUCTURE as an unique object via internet (serialized), not many request (the structure is not very heavy, at least in my case).
As I said before, this is a solution for a very dissapointing case, which I found while programming. If you search in google: "serialize treenode" you will find many other people trying to do that, but with the same problem I had. I only found a simple solution and I posted it. I never thought to have so much problems by posting a solution for a very defined problem (which so many people had before, I wish I would had this aid and not spend so much time trying to store a tree structure into a bynari file).

"Due to the programming work is a bull-sh*t, the Serialize of a TreeNode object does not work as it is said in the Microsoft’s online page, or other web pages, i.ex., Object Serialization using C# in this website."

I voted you a 1 due to the "bull-sh*t." I don't think cusing is any big deal, but articles are supposed to be professional literature for the community to use to educate itself. That kind of language doesn't belong here.

I'm going to become rich when I create a device that allows me to punch people in the face over the internet.

"If an Indian asked a programming question in the forest, would it still be urgent?" - John Simmons / outlaw programmer

OK, translation (I supossed, for your surname, you talked spanish). And if you feel better, I can write it in french too.
Ok, if you thing that such language is not useful in this webpage, maybe I should have wrote this article at a Microsoft's website, insulting who wrote the TreeNode class, where I spent almost a whole month of my life (well, a few hours of the month, but slepping very bad) and finally to find that Serializing a TreeNode was so stupid, but very hidden. And if you don't trust me, try to inherit the TreeNode class and serialize it, then let me know if you feel so happy working as a programmer.
Certainly, someone that want to punch me for such stupid thing (unless you was who wrote the TreeNode class at Microsoft's) must not be very happy working at a programming factory (I don't use to punch anyone, even more if I don't know him). At any rate, I already changed my article.
I preffer not to continue spending my time, but if you have any doubt of how badly .NET platform is made (I guess trying to copy Java and how it works -not call it a virtual machine, that works very slow, we will call it Framework, it's the same that works better) I just said, try to Serialize an inherited TreeNode. I surfered all Internet, and I did not find ANYTHING.