TreeView Private variable clearing - c#

I created a private variable
private TreeView currentFullTree;
After that I run through a database and create a nice treeview with parent, child, child nodes. That works fine also. Once the treeview is created I set my private variable to
currentFullTree = treeView1;
That populates perfectly fine and I can even extract each node and re-create the tree exactly how it looked originally from a different function.
Now this is where I'm getting lost. I've created a filter/search function separate from where I created the treeview or re-create the treeview. I want to only display the nodes that match the text provided. Before I perform the search I do a treeView1.Nodes.Clear(); so it looks nice and isn't cluttery.
When I do this, it also empties out my private variable I created! I'm not entirely sure why it is doing this. I was thinking since it is just a TreeView variable I would be able to store my treeview in there and access it as I please. I'm not sure if it's something silly I'm overlooking, but any help is appreciated.
Thanks,
Tim

Your currentFullTree and treeView1 are pointing to the same object because those variables are of reference type.
Either you have to keep copy of whole tree or just tree nodes.
private TreeView currentFullTree;
private List<TreeNode> treeNodes;
and before clearing tree just add them to the list:
treeNodes.AddRange(treeView1.Nodes.OfType<TreeNode>());
treeView1.Nodes.Clear();
and when you want to show full tree (original) then add nodes from list back to tree view.

Your variable is only a reference to an object.
You need to clone it to be able to have different treeview (one for reference and one for display).
see https://msdn.microsoft.com/en-us/library/ms173109.aspx
this may also be usefull for cloning the tree https://msdn.microsoft.com/en-us/library/system.windows.forms.treenode.clone%28v=vs.110%29.aspx
but be aware of this:
Remarks
The tree structure from the tree node being cloned and below is
copied. Any child tree nodes assigned to the TreeNode being cloned are
included in the new tree node and subtree.
The Clone method performs a shallow copy of the node. If the value of
the Tag property is a reference type, both the original and cloned
copy will point to the same single instance of the Tag value.

Related

Implement WPF TreeView of the same structure as another TreeView

I have a TreeView which data source is generated in runtime through code to which I don't have access. Its hierarchical data, nodes of tree with 2, 3 or 4 depth levels. I have to make the same structured tree with RadioButtons corresponding to every object in first tree. Is there a way to iterate through every element of TreeView or another method to do my task?
In WPF, we use DataTemplates, or in your case HierarchicalDataTemplates to define how our data should be presented. You already have the data in the first TreeView and that should be accessible from its ItemsSource or Items properties. Therefore, all you need to do is to define another HierarchicalDataTemplate to display the same data object the way that you want it. There is no need to manually iterate through all of the nodes from the original TreeView.

Winforms- design pattern to couple treenodes to datastructure

I currently have a data structure that displays file system tree's its basically an object with an array list of like typed objects. I want to display this in a treeview, and need to run some code when the tree view nodes are expanded, collapsed, selected, etc.
My question- is there a design pattern, or method of coupling between the data structure and the treeview that wont require me to search the whole DS tree for the selected node each time the user selects something?
Currently I am searching the data structure for a node with the same Text and Tag property as the selected node each time a relevant tree view event fires. I run into scenarios where if the node is not a leaf I have to go and re-search for its parent node, and I'm concerned about performance with large tree
Keep in mind, the data structure already inherits an object so I cant simply extend the treenode class.
Any help is greatly appreciated
You can still extend TreeNode but using composition to add an extra property that maps to the object that node represents.
You can also move the logic for the child nodes to this tree node rather than have it outside
public class DomainClass { /*...*/ }
public class DomainTreeNode: TreeNode
{
public DomainClass Element { get; private set; }
public DomainTreeNode(DomainClass element): base(element.Name)
{
Element = element;
/* iterate on element's children and add them to the node's
Childs collection ...*/
}
}

Empty expandable treenode in C#

I want to create an expandable empty treenode in C#, i.e. a treenode which is empty and has the [+] sign beside it. The reason is because initially it is empty, but once a node is clicked, I want to populate it with many child nodes.
The only problem I am facing is that empty treenodes aren't expandable, so I don't know what to do. Is there a way to solve this problem, or are there any workarounds?
You have to redraw the tree itself, or create an empty node and simply remove it when the parent node is expanded.
Personally, I'd go for option b). I've done this before, a while ago and thanks to the events raised by the TreeView it pretty easy to accomplish.
You can give the empty node a value like 'Loading...' so it gives some feedback to the user as well. :)
Add a dummy child node, and remove it when you expand.
Have a look at Josh Smiths excellent tutorial on treeviews. It allows lazy loading of child tree nodes by having a dummy node that is removed upon expansion.

Treeview Refresh Questions

I have a Treeview that the user cannot edit. The way I'm trying to refresh is clearing the entire tree and re-adding all the nodes (and children). I'm accomplishing this by the following lines of code:
treeView.BeginUpdate(); //Freeze drawing
treeView.Nodes.Clear(); //Empty Tree
addAllNodes(); //This adds the nodes for the tree and sets their name/text property
treeView.EndUpdate(); //Unfreeze drawing
I've tried adding the Update and Refresh method before I call addAllNodes but hasn't made a difference. Doing the above gets me an error:
System.ArgumentException: Cannot add or insert the item 'NodeNameHere' in more than one place. You must first remove it from its current location or clone it
My first question is, what am I doing to cause this error and how can I properly refresh my tree?
My second question is, after the refresh is there any way I can restore the user's expanded nodes? (so that everything does not end up collapsed)
each node has a path (called something like .Path or .FullPath; dont have VS open right now). So you can walk your nodes before you clear them and record all the expanded nodes, then walk them again after refresh and see if the node's path matches a stored one.. if it does, expand it.

WPF FrameworkElement Parent and Moving a UIElement

I'm trying to move a control from one parent to another (if this will work I'm not quite sure). I can get a hold of the control that I want to move. Here is my code:
public void MoveElement(UIElement uiElement)
{
var element = ((FrameworkElement)uiElement).Parent;
//TODO:Remove from parent
myControl.Children.Add(uiElement);
}
When I hit the last statment an ArgumentException is thrown stating "Specified Visual is already a child of another Visual or the root of a CompositionTarget." The strange thing is that Parent is returning null. How do locate the parent? Will this even work?
EDIT: I don't think actually moving an element is the answer to my problem. I'm working with the Visual Studio SDK and was able to get a hold of the UIElement that makes up the editor pane (extends DockPanel). I was trying to move the control from the standard editor into a custom tool window I'm developing.
This is proving to be a hack and I realized that I need multiple instances of the same control so I think a more complex solution (and less of a hack) is in store.
The Parent property refers to the logical tree, and the docs note that "Parent may be null in cases where an element was instantiated, but is not attached to any logical tree that eventually connects to the page level root element, or the application object." For example, the root element of a DataTemplate instantiated in a ListBox has a null Parent.
Try using VisualTreeHelper.GetParent instead. The visual tree is the lower-level representation of how WPF elements are organised, and gives you access to all the extra "bits" that things like templating throw in there. For example, calling VisualTreeHelper.GetParent on the root element of a DataTemplate instantiated in a ListBox returns a ContentPresenter.
Note that just because you can get hold of the parent visual does not necessarily mean you'll be able to remove it. Some elements, such as Panels, provide methods for this. But if the element you locate is part of, say, a CheckBox, I don't think you'll be able to remove it.
If you can provide a bit more context for what you're trying to achieve by moving controls around the visual tree, people may be able to offer more specific advice or alternative approaches.

Categories