Using a TreeNode as a User Setting












2















I'm trying to use a TreeNode (System.Windows.Forms.TreeNode) as a user setting for one of my applications.



if(treeView.SelectedNode != null)
{
Properties.Settings.Default.SelectedTreeNode = treeView.SelectedNode;
Properties.Settings.Default.Save();
}


Then on Application Load I'm trying to use that Setting



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= Properties.Settings.Default.SelectedTreeNode;


but no matter what I do, Properties.Settings.Default.SelectedTreeNode is always null when I reload the application.



I've also tried just using an Object and casting to a TreeNode, but that doesn't work either.



I really don't want to use string Settings for this, and want to stick with TreeNode if possible, but a serialized TreeNode would work if there is no way to use a TreeNode. I'm just not too familiar with Serialization.










share|improve this question




















  • 2





    a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

    – TaW
    Nov 14 '18 at 22:40








  • 1





    So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

    – TaW
    Nov 16 '18 at 13:03
















2















I'm trying to use a TreeNode (System.Windows.Forms.TreeNode) as a user setting for one of my applications.



if(treeView.SelectedNode != null)
{
Properties.Settings.Default.SelectedTreeNode = treeView.SelectedNode;
Properties.Settings.Default.Save();
}


Then on Application Load I'm trying to use that Setting



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= Properties.Settings.Default.SelectedTreeNode;


but no matter what I do, Properties.Settings.Default.SelectedTreeNode is always null when I reload the application.



I've also tried just using an Object and casting to a TreeNode, but that doesn't work either.



I really don't want to use string Settings for this, and want to stick with TreeNode if possible, but a serialized TreeNode would work if there is no way to use a TreeNode. I'm just not too familiar with Serialization.










share|improve this question




















  • 2





    a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

    – TaW
    Nov 14 '18 at 22:40








  • 1





    So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

    – TaW
    Nov 16 '18 at 13:03














2












2








2


1






I'm trying to use a TreeNode (System.Windows.Forms.TreeNode) as a user setting for one of my applications.



if(treeView.SelectedNode != null)
{
Properties.Settings.Default.SelectedTreeNode = treeView.SelectedNode;
Properties.Settings.Default.Save();
}


Then on Application Load I'm trying to use that Setting



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= Properties.Settings.Default.SelectedTreeNode;


but no matter what I do, Properties.Settings.Default.SelectedTreeNode is always null when I reload the application.



I've also tried just using an Object and casting to a TreeNode, but that doesn't work either.



I really don't want to use string Settings for this, and want to stick with TreeNode if possible, but a serialized TreeNode would work if there is no way to use a TreeNode. I'm just not too familiar with Serialization.










share|improve this question
















I'm trying to use a TreeNode (System.Windows.Forms.TreeNode) as a user setting for one of my applications.



if(treeView.SelectedNode != null)
{
Properties.Settings.Default.SelectedTreeNode = treeView.SelectedNode;
Properties.Settings.Default.Save();
}


Then on Application Load I'm trying to use that Setting



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= Properties.Settings.Default.SelectedTreeNode;


but no matter what I do, Properties.Settings.Default.SelectedTreeNode is always null when I reload the application.



I've also tried just using an Object and casting to a TreeNode, but that doesn't work either.



I really don't want to use string Settings for this, and want to stick with TreeNode if possible, but a serialized TreeNode would work if there is no way to use a TreeNode. I'm just not too familiar with Serialization.







c# winforms






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 13:02









TaW

41.4k62864




41.4k62864










asked Nov 14 '18 at 20:57









John GrabanskiJohn Grabanski

294515




294515








  • 2





    a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

    – TaW
    Nov 14 '18 at 22:40








  • 1





    So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

    – TaW
    Nov 16 '18 at 13:03














  • 2





    a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

    – TaW
    Nov 14 '18 at 22:40








  • 1





    So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

    – TaW
    Nov 16 '18 at 13:03








2




2





a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

– TaW
Nov 14 '18 at 22:40







a) TreeNode actually is serializable but it doesn't come back in a restart. It does get stored while the app runs, though. I can't explain why that is so or how to workaround. color is not serializable but it works fine !? - b) do note that even if it came back it should still be a new copy of the node and your code should not select it in the tree, if that was actually what you meant. If you want to add it to the treeview along with labels and childnodes you will have to write code for that..!

– TaW
Nov 14 '18 at 22:40






1




1





So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

– TaW
Nov 16 '18 at 13:03





So you do not, as you wrote, want to store a TreeNode itself, with all its chil nodes, tags etc.. but only a reliable way to select that node.. Quite misleading question!

– TaW
Nov 16 '18 at 13:03












2 Answers
2






active

oldest

votes


















3














Even if you could store TreeNode in settings, you cannot assign deserialized node to SelectedNode property of TreeView. TreeNode is reference type and since the instance which you load from setting is not the same instance which exists in the tree, the assignment doesn't make sense and will not work. It's already mentioned in point b in the comment by Taw.



To preserve selected node in settings, it's better to rely on a string property. You have at least two options:




  1. Store Name property of the node in settings

  2. Store FullPath property of the node in settings


Option 1 - Name Property



Each TreeNode has a Name property which can be used to find the node.





  • Assign a unique key to nodes when creating them:



    treeView1.Nodes.Add("key", "text");


  • When saving data, store treeView1.SelectedNode.Name in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.Find("some key", true).FirstOrDefault();



Option 2 - FullPath Property



Each TreeNode has a FullPath which gets the path from the root tree node to the current tree node.




The path consists of the labels of all the tree nodes that must be
navigated to reach this tree node, starting at the root tree node. The
node labels are separated by the delimiter character specified in the
PathSeparator property of the TreeView control that contains this
node.





  • When creating node, you don't need to do special settings. Every node has FullPath.


  • When saving data, store treeView1.SelectedNode.FullPath in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.FindByPath(@"pathtothenode");



In above code, FindByPath is an extension method which you can create to find the ndoe by path:



using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}





share|improve this answer





















  • 1





    I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

    – John Grabanski
    Nov 15 '18 at 13:49






  • 1





    plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

    – TaW
    Nov 16 '18 at 13:06





















0














What's happening here is that the call to the Save method attempts to serialize the node in order to store it in the User.config file. If you inspect this file, you will find that the node is empty:



<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="..." >
<section name="SomeProject.Properties.Settings" type="..." allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<SomeProject.Properties.Settings>
<setting name="SelectedTreeNode" serializeAs="Xml">
<value /> <!-- The node was not serialized! -->
</setting>
</SomeProject.Properties.Settings>
</userSettings>
</configuration>


The reason is probably that the Save method is attempting the serialization using the XmlSerializer class, which does not respect the ISerializable interface, which is how serialization is implemented for the TreeNode class. It blows up internally at some point and it swallows the error, leaving an empty value instead.



What you can do to get around this is serialize the TreeNode object using a proper serialization method, which is a formatter. Formatters respect the ISerializable interface. You can then store the resulting string in the setting and later read it and materialize it into the node:



if (string.IsNullOrWhiteSpace(Properties.Settings.Default.SelectedTreeNode))
{
Properties.Settings.Default.SelectedTreeNode = SerializeNode(treeView.SelectedNode);
Properties.Settings.Default.Save();
}


On application load:



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= DeserializeNode(Properties.Settings.Default.SelectedTreeNode);


The serialization functions:



public string SerializeNode(TreeNode node)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, node);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var serialized = reader.ReadToEnd();
return serialized;
}
}
}

public TreeNode DeserializeNode(string nodeString)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.Write(nodeString);
writer.Flush();
stream.Position = 0;
var node = (TreeNode)formatter.Deserialize(stream);
return node;
}
}
}


For this answer, I am using the SoapFormatter class. You will need to add a reference to System.Runtime.Serialization.Formatters.Soap.






share|improve this answer


























  • Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

    – TaW
    Nov 16 '18 at 13:05











  • Thank you, @TaW!

    – JuanR
    Nov 16 '18 at 14:09











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308604%2fusing-a-treenode-as-a-user-setting%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














Even if you could store TreeNode in settings, you cannot assign deserialized node to SelectedNode property of TreeView. TreeNode is reference type and since the instance which you load from setting is not the same instance which exists in the tree, the assignment doesn't make sense and will not work. It's already mentioned in point b in the comment by Taw.



To preserve selected node in settings, it's better to rely on a string property. You have at least two options:




  1. Store Name property of the node in settings

  2. Store FullPath property of the node in settings


Option 1 - Name Property



Each TreeNode has a Name property which can be used to find the node.





  • Assign a unique key to nodes when creating them:



    treeView1.Nodes.Add("key", "text");


  • When saving data, store treeView1.SelectedNode.Name in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.Find("some key", true).FirstOrDefault();



Option 2 - FullPath Property



Each TreeNode has a FullPath which gets the path from the root tree node to the current tree node.




The path consists of the labels of all the tree nodes that must be
navigated to reach this tree node, starting at the root tree node. The
node labels are separated by the delimiter character specified in the
PathSeparator property of the TreeView control that contains this
node.





  • When creating node, you don't need to do special settings. Every node has FullPath.


  • When saving data, store treeView1.SelectedNode.FullPath in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.FindByPath(@"pathtothenode");



In above code, FindByPath is an extension method which you can create to find the ndoe by path:



using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}





share|improve this answer





















  • 1





    I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

    – John Grabanski
    Nov 15 '18 at 13:49






  • 1





    plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

    – TaW
    Nov 16 '18 at 13:06


















3














Even if you could store TreeNode in settings, you cannot assign deserialized node to SelectedNode property of TreeView. TreeNode is reference type and since the instance which you load from setting is not the same instance which exists in the tree, the assignment doesn't make sense and will not work. It's already mentioned in point b in the comment by Taw.



To preserve selected node in settings, it's better to rely on a string property. You have at least two options:




  1. Store Name property of the node in settings

  2. Store FullPath property of the node in settings


Option 1 - Name Property



Each TreeNode has a Name property which can be used to find the node.





  • Assign a unique key to nodes when creating them:



    treeView1.Nodes.Add("key", "text");


  • When saving data, store treeView1.SelectedNode.Name in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.Find("some key", true).FirstOrDefault();



Option 2 - FullPath Property



Each TreeNode has a FullPath which gets the path from the root tree node to the current tree node.




The path consists of the labels of all the tree nodes that must be
navigated to reach this tree node, starting at the root tree node. The
node labels are separated by the delimiter character specified in the
PathSeparator property of the TreeView control that contains this
node.





  • When creating node, you don't need to do special settings. Every node has FullPath.


  • When saving data, store treeView1.SelectedNode.FullPath in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.FindByPath(@"pathtothenode");



In above code, FindByPath is an extension method which you can create to find the ndoe by path:



using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}





share|improve this answer





















  • 1





    I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

    – John Grabanski
    Nov 15 '18 at 13:49






  • 1





    plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

    – TaW
    Nov 16 '18 at 13:06
















3












3








3







Even if you could store TreeNode in settings, you cannot assign deserialized node to SelectedNode property of TreeView. TreeNode is reference type and since the instance which you load from setting is not the same instance which exists in the tree, the assignment doesn't make sense and will not work. It's already mentioned in point b in the comment by Taw.



To preserve selected node in settings, it's better to rely on a string property. You have at least two options:




  1. Store Name property of the node in settings

  2. Store FullPath property of the node in settings


Option 1 - Name Property



Each TreeNode has a Name property which can be used to find the node.





  • Assign a unique key to nodes when creating them:



    treeView1.Nodes.Add("key", "text");


  • When saving data, store treeView1.SelectedNode.Name in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.Find("some key", true).FirstOrDefault();



Option 2 - FullPath Property



Each TreeNode has a FullPath which gets the path from the root tree node to the current tree node.




The path consists of the labels of all the tree nodes that must be
navigated to reach this tree node, starting at the root tree node. The
node labels are separated by the delimiter character specified in the
PathSeparator property of the TreeView control that contains this
node.





  • When creating node, you don't need to do special settings. Every node has FullPath.


  • When saving data, store treeView1.SelectedNode.FullPath in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.FindByPath(@"pathtothenode");



In above code, FindByPath is an extension method which you can create to find the ndoe by path:



using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}





share|improve this answer















Even if you could store TreeNode in settings, you cannot assign deserialized node to SelectedNode property of TreeView. TreeNode is reference type and since the instance which you load from setting is not the same instance which exists in the tree, the assignment doesn't make sense and will not work. It's already mentioned in point b in the comment by Taw.



To preserve selected node in settings, it's better to rely on a string property. You have at least two options:




  1. Store Name property of the node in settings

  2. Store FullPath property of the node in settings


Option 1 - Name Property



Each TreeNode has a Name property which can be used to find the node.





  • Assign a unique key to nodes when creating them:



    treeView1.Nodes.Add("key", "text");


  • When saving data, store treeView1.SelectedNode.Name in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.Find("some key", true).FirstOrDefault();



Option 2 - FullPath Property



Each TreeNode has a FullPath which gets the path from the root tree node to the current tree node.




The path consists of the labels of all the tree nodes that must be
navigated to reach this tree node, starting at the root tree node. The
node labels are separated by the delimiter character specified in the
PathSeparator property of the TreeView control that contains this
node.





  • When creating node, you don't need to do special settings. Every node has FullPath.


  • When saving data, store treeView1.SelectedNode.FullPath in settings.



  • To select the node based on the settings:



    treeView1.SelectedNode = treeView1.Nodes.FindByPath(@"pathtothenode");



In above code, FindByPath is an extension method which you can create to find the ndoe by path:



using System.Windows.Forms;
public static class TreeViewExtensiona
{
public static TreeNode FindByPath(this TreeNodeCollection nodes, string path)
{
TreeNode found = null;
foreach (TreeNode n in nodes)
{
if (n.FullPath == path)
found = n;
else
found = FindByPath(n.Nodes, path);
if (found != null)
return found;
}
return null;
}
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 0:22

























answered Nov 15 '18 at 0:15









Reza AghaeiReza Aghaei

67.2k856167




67.2k856167








  • 1





    I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

    – John Grabanski
    Nov 15 '18 at 13:49






  • 1





    plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

    – TaW
    Nov 16 '18 at 13:06
















  • 1





    I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

    – John Grabanski
    Nov 15 '18 at 13:49






  • 1





    plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

    – TaW
    Nov 16 '18 at 13:06










1




1





I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

– John Grabanski
Nov 15 '18 at 13:49





I used Option 2 here. I feel FullPath is exactly what I wanted, and the FIndByPath extension is very simple.

– John Grabanski
Nov 15 '18 at 13:49




1




1





plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

– TaW
Nov 16 '18 at 13:06







plus1 for mindreading :-) The other answer is quite useful when one actually wants to store a treenode.

– TaW
Nov 16 '18 at 13:06















0














What's happening here is that the call to the Save method attempts to serialize the node in order to store it in the User.config file. If you inspect this file, you will find that the node is empty:



<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="..." >
<section name="SomeProject.Properties.Settings" type="..." allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<SomeProject.Properties.Settings>
<setting name="SelectedTreeNode" serializeAs="Xml">
<value /> <!-- The node was not serialized! -->
</setting>
</SomeProject.Properties.Settings>
</userSettings>
</configuration>


The reason is probably that the Save method is attempting the serialization using the XmlSerializer class, which does not respect the ISerializable interface, which is how serialization is implemented for the TreeNode class. It blows up internally at some point and it swallows the error, leaving an empty value instead.



What you can do to get around this is serialize the TreeNode object using a proper serialization method, which is a formatter. Formatters respect the ISerializable interface. You can then store the resulting string in the setting and later read it and materialize it into the node:



if (string.IsNullOrWhiteSpace(Properties.Settings.Default.SelectedTreeNode))
{
Properties.Settings.Default.SelectedTreeNode = SerializeNode(treeView.SelectedNode);
Properties.Settings.Default.Save();
}


On application load:



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= DeserializeNode(Properties.Settings.Default.SelectedTreeNode);


The serialization functions:



public string SerializeNode(TreeNode node)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, node);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var serialized = reader.ReadToEnd();
return serialized;
}
}
}

public TreeNode DeserializeNode(string nodeString)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.Write(nodeString);
writer.Flush();
stream.Position = 0;
var node = (TreeNode)formatter.Deserialize(stream);
return node;
}
}
}


For this answer, I am using the SoapFormatter class. You will need to add a reference to System.Runtime.Serialization.Formatters.Soap.






share|improve this answer


























  • Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

    – TaW
    Nov 16 '18 at 13:05











  • Thank you, @TaW!

    – JuanR
    Nov 16 '18 at 14:09
















0














What's happening here is that the call to the Save method attempts to serialize the node in order to store it in the User.config file. If you inspect this file, you will find that the node is empty:



<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="..." >
<section name="SomeProject.Properties.Settings" type="..." allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<SomeProject.Properties.Settings>
<setting name="SelectedTreeNode" serializeAs="Xml">
<value /> <!-- The node was not serialized! -->
</setting>
</SomeProject.Properties.Settings>
</userSettings>
</configuration>


The reason is probably that the Save method is attempting the serialization using the XmlSerializer class, which does not respect the ISerializable interface, which is how serialization is implemented for the TreeNode class. It blows up internally at some point and it swallows the error, leaving an empty value instead.



What you can do to get around this is serialize the TreeNode object using a proper serialization method, which is a formatter. Formatters respect the ISerializable interface. You can then store the resulting string in the setting and later read it and materialize it into the node:



if (string.IsNullOrWhiteSpace(Properties.Settings.Default.SelectedTreeNode))
{
Properties.Settings.Default.SelectedTreeNode = SerializeNode(treeView.SelectedNode);
Properties.Settings.Default.Save();
}


On application load:



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= DeserializeNode(Properties.Settings.Default.SelectedTreeNode);


The serialization functions:



public string SerializeNode(TreeNode node)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, node);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var serialized = reader.ReadToEnd();
return serialized;
}
}
}

public TreeNode DeserializeNode(string nodeString)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.Write(nodeString);
writer.Flush();
stream.Position = 0;
var node = (TreeNode)formatter.Deserialize(stream);
return node;
}
}
}


For this answer, I am using the SoapFormatter class. You will need to add a reference to System.Runtime.Serialization.Formatters.Soap.






share|improve this answer


























  • Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

    – TaW
    Nov 16 '18 at 13:05











  • Thank you, @TaW!

    – JuanR
    Nov 16 '18 at 14:09














0












0








0







What's happening here is that the call to the Save method attempts to serialize the node in order to store it in the User.config file. If you inspect this file, you will find that the node is empty:



<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="..." >
<section name="SomeProject.Properties.Settings" type="..." allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<SomeProject.Properties.Settings>
<setting name="SelectedTreeNode" serializeAs="Xml">
<value /> <!-- The node was not serialized! -->
</setting>
</SomeProject.Properties.Settings>
</userSettings>
</configuration>


The reason is probably that the Save method is attempting the serialization using the XmlSerializer class, which does not respect the ISerializable interface, which is how serialization is implemented for the TreeNode class. It blows up internally at some point and it swallows the error, leaving an empty value instead.



What you can do to get around this is serialize the TreeNode object using a proper serialization method, which is a formatter. Formatters respect the ISerializable interface. You can then store the resulting string in the setting and later read it and materialize it into the node:



if (string.IsNullOrWhiteSpace(Properties.Settings.Default.SelectedTreeNode))
{
Properties.Settings.Default.SelectedTreeNode = SerializeNode(treeView.SelectedNode);
Properties.Settings.Default.Save();
}


On application load:



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= DeserializeNode(Properties.Settings.Default.SelectedTreeNode);


The serialization functions:



public string SerializeNode(TreeNode node)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, node);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var serialized = reader.ReadToEnd();
return serialized;
}
}
}

public TreeNode DeserializeNode(string nodeString)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.Write(nodeString);
writer.Flush();
stream.Position = 0;
var node = (TreeNode)formatter.Deserialize(stream);
return node;
}
}
}


For this answer, I am using the SoapFormatter class. You will need to add a reference to System.Runtime.Serialization.Formatters.Soap.






share|improve this answer















What's happening here is that the call to the Save method attempts to serialize the node in order to store it in the User.config file. If you inspect this file, you will find that the node is empty:



<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="..." >
<section name="SomeProject.Properties.Settings" type="..." allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<SomeProject.Properties.Settings>
<setting name="SelectedTreeNode" serializeAs="Xml">
<value /> <!-- The node was not serialized! -->
</setting>
</SomeProject.Properties.Settings>
</userSettings>
</configuration>


The reason is probably that the Save method is attempting the serialization using the XmlSerializer class, which does not respect the ISerializable interface, which is how serialization is implemented for the TreeNode class. It blows up internally at some point and it swallows the error, leaving an empty value instead.



What you can do to get around this is serialize the TreeNode object using a proper serialization method, which is a formatter. Formatters respect the ISerializable interface. You can then store the resulting string in the setting and later read it and materialize it into the node:



if (string.IsNullOrWhiteSpace(Properties.Settings.Default.SelectedTreeNode))
{
Properties.Settings.Default.SelectedTreeNode = SerializeNode(treeView.SelectedNode);
Properties.Settings.Default.Save();
}


On application load:



if (Properties.Settings.Default.SelectedTreeNode != null)
treeView.SelectedNode= DeserializeNode(Properties.Settings.Default.SelectedTreeNode);


The serialization functions:



public string SerializeNode(TreeNode node)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, node);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var serialized = reader.ReadToEnd();
return serialized;
}
}
}

public TreeNode DeserializeNode(string nodeString)
{
var formatter = new SoapFormatter();
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.Write(nodeString);
writer.Flush();
stream.Position = 0;
var node = (TreeNode)formatter.Deserialize(stream);
return node;
}
}
}


For this answer, I am using the SoapFormatter class. You will need to add a reference to System.Runtime.Serialization.Formatters.Soap.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 14:47

























answered Nov 14 '18 at 22:55









JuanRJuanR

5,0901928




5,0901928













  • Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

    – TaW
    Nov 16 '18 at 13:05











  • Thank you, @TaW!

    – JuanR
    Nov 16 '18 at 14:09



















  • Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

    – TaW
    Nov 16 '18 at 13:05











  • Thank you, @TaW!

    – JuanR
    Nov 16 '18 at 14:09

















Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

– TaW
Nov 16 '18 at 13:05





Great answer to he question as written. Pitty it is not what ghe actually meant but may come useful to folks mislead by the question tile etc.. I wish I could upvote more than once..

– TaW
Nov 16 '18 at 13:05













Thank you, @TaW!

– JuanR
Nov 16 '18 at 14:09





Thank you, @TaW!

– JuanR
Nov 16 '18 at 14:09


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308604%2fusing-a-treenode-as-a-user-setting%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python