Question

TTreeNode does not have a Visible property, so the obvious option does not exist. Is there any other way to make a TTreeNode and all its child nodes invisible? Of course I want to be able to make it visible again later.

This is with Delphi 2007.

Note#1: I am aware of the alternative TVirtualTreeView, and I will check it out if there is no easy way to accomplish this with TTreeView.

Note#2: I need the option only for top level nodes. The ones I want to hide usually don't even have children.

Was it helpful?

Solution

It's a good idea to separate data from the user interface, and this issue with tree views is a good example - don't store data in a tree view. I often have a non-visual unit that contains a structured class that stores data. A user interface unit can have a treeview that can displays (a configurable subset of) data from that class. There are a variety of ways to move data between the two. This type of isolation requires a bit of planning, but provides much greater flexibility and stability.

OTHER TIPS

if you want to use a better tree component, why not use Virtualtreeview. It is one of the best components ever developed for Delphi and it's free to use with source! But there is maybe a logical problem with hiding a ttreenode! Should the tree show a + sign when no nodes are visible?

http://wiki.lazarus.freepascal.org/VirtualTreeview

TTreeView is a wrapper for the standard Windows tree view, which (judging from the documentation on MSDN) doesn't allow to hide tree nodes. It does make sense too, as the tree view is known to not scale to a large number of nodes, so hiding tree nodes instead of removing everything that isn't necessary would be a bad idea.

You can make your life a little easier if you remove and insert only the top level node (the one you wish to hide), and create all child nodes in the OnExpanding event of the re-added node. For that you just need to set the HasChildren property of the node to true.

The only way to "hide" a node in TTreeView is to actually remove it. Then, to "show" the node, you simply re-insert it again.

How I made it in DXE5 with standard TTreeView. I think it will be helpful for some guys. I've made it simple for example:

1. Item that must be hidden. I set ImageIndex of it to 2.

  var
    Node:TTreeNode;
  begin
  ...
  Node:=Tree.Items.AddChild(ParentNode,'Text');
  Node.ImageIndex:=2;

2. Now I set onAdvancedCustomDrawItem event of TTreeView.

  if Node.ImageIndex=2 then
  begin
    DefaultDraw:=false;
    Node.Parent.HasChildren:=false;
  end;

3. Check it with onClick event of TTreeView:

var
 Tree:TTreeView;
 Node:TTreeNode;
begin
  Tree:=Sender as TTreeView;
  if Tree.Selected.Index>-1 then
   if Tree.Selected.HasChildren then
    if Tree.Selected.getFirstChild.ImageIndex=2 then
     showmessage(Tree.Selected.getFirstChild.Text);

Done. I hope it will helps you.

I solve this issue by moving the node to another non-expanded node and vice versa. I done it in the on expanding event handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top