Background
I worked a few weeks in an application that required the data to be displayed in a hierarchical structure that exemplifies and makes it easier to understand
the structure of this information in particular.
Since the data is ever changing, and the UI must not be closed, and instead it must to be refreshed every certain time lapse, the default TreeView
that is shown
in the ToolBox of Visual Studio is out of the question because as it's well known, it doesn't preserve states in case the UI should be refreshed, and what happens when UI
is refreshed is that it returns to its original state when it was first drawn. Of course, you can do some "stuff" in the code to manage this behavior,
but it tends to be tedious and boring, what is traduced in waste of time.
Here is a brief explanation...
TreeView (System.Windows.Forms.TreeView)
The TreeView
, as it's known, is a control that helps to manage hierarchical structures on a simple view of tree; it has some basic behaviors that can make
it more easier to bind data, show XML hierarchical structures, etc., but the most interesting thing about this kind of controls is that you can improve them and make
them do exactly what you need them to do.
Inheritance
Inheritance is a way to compartmentalize and reuse code by creating objects that have attributes and behaviors that can be based on previously created objects.
The inheritance allows us work with simple controls like TreeView
by taking advantage of their basic behaviors and lets us improve the control by adding new members
to control some behavior that we need from the control.
In Visual C#, we can write a class definition that inherits from TreeView
like:
public partial class customTreeView : System.Windows.Forms.TreeView
Development
Because of the above, I decided to develop my own TreeView that preserves the states of its nodes in many hierarchy levels, to make
it a bit more flexible and comfortable for the application.
I have used an implementation of the original TreeView
class, but added some new properties and methods that can help us use it to preserve our TreeView state.
A Control Library...
I developed a Control Library that contains our new customTreeView
as I named it. The library can be referenced in any project as a
.dll component or can be added into the ToolBox in Visual Studio.
The Test Project...
In this project, our new behavior is being tested. You can test the way it works, side by side a normal TreeView, and the way you can implement this in your own application.
Now a brief explanation of the members added to the new customTreeView
...
Public Custom Properties
PreserveTreeState
Basically, this property allow us to to tell our custom TreeView if we want to preserve or not its tree state.
private bool _preseveTreeState;
public bool PreseveTreeState
{
get { return _preseveTreeState; }
set { _preseveTreeState = value; }
}
TreeState_dic
This is a System.Collections.Generic.Doctionary<string, bool>
that allows us to store our tree state, and it depends on the PreserveTreeState
value.
True
to store the tree state, false otherwise.
private Dictionary<string, bool> treeState_dic = new Dictionary<string, bool>();
public Dictionary<string, bool> TreeState_dic
{
get { return treeState_dic; }
set { treeState_dic = value; }
}
Public Custom Methods
SaveTreeState()
We must call this if we want to save our tree state. It fills the TreeState_dic
object, and depends on the
PreserveTreeState
value. True
to store the tree state, false otherwise.
public void SaveTreeState()
RestoreTreeState()
We must call this if we want to restore the last saved state of our tree. It uses the TreeState_dic
object information to redraw the last saved state,
and depends on the PreserveTreeState
value. True
to restore the tree state, false otherwise.
Definition:
public void RestoreTreeState()
Private Custom Methods
saveTreeState(TreeView tree)
Internally, initialize the process to save our tree state. It begins to fill our TreeState_dic
object.
private void saveTreeState(TreeView tree)
...where tree
is the current customTreeView
.
saveTreeState_level2(TreeNode tNode, string parentDicKey)
It is a recursive method that creates the next keys in our TreeState_dic
object for the next hierarchy levels.
private void saveTreeState_level2(TreeNode tNode, string parentDicKey)
...where tNode
is the current node of customTreeView
, and parentDicKey
is the parent dictionary key of the current node inside
the TreeState_dic
object.
restoreTreeState(TreeView tree)
Internally, begins to search in our TreeState_dic
object, for each of our tree node's values for the IsExpanded
property.
private void restoreTreeState(TreeView tree)
...where tree
is the current customTreeView
.
restoreTreeState_level2(TreeNode tNode, string parentDicKey)
It is a recursive method that searches for the next hierarchy levels of our TreeState_dic
object to load each value to the treeview.
private void restoreTreeState_level2(TreeNode tNode, string parentDicKey)
...Where tNode
is the current node of customTreeView
, and parentDicKey
is the parent dictionary key of the current
node inside the TreeState_dic
object.
Conclusion
As a final idea, I must say that was only a little thing that you can improve in a TreeView control. There are so many behaviors that you can develop
from this and other controls to get better performance for your applications, so make the best, and always look for a way to improve your code...