Drawing the tree nodes is much tricker than it might sound. When you perform custom drawing of the entire node it does not modify how the mouse interacts with the node itself and so you need to ensure that the drawing is aligned with the expected mouse locations. For example, when drawing check boxes I must ensure that I draw them in the exact pixel offset from the left of the control. Otherwise they will look nice but the users’ clicks will not match the drawn location and so the interaction will not work as expected.

Here you can see the drawing of check boxes and how the highlight for the selected/tracking node is immediately adjacent to the check box itself. This is not very pretty and I would prefer a pixel gap between the check box and the highlighting but this is not possible because that is the method expected by the tree control.

You can assign an ImageList to the KryptonTreeControl and then use the per-node image index to draw images by the nodes. Luckily the standard tree does have a gap between the right of the image and the node highlighting so the appearance looks tidier than for check boxes.

Also implemented is the use of the StateImageList that is used to provide an optional per-node image at the left of the node drawing. In this example I used set this up on the top two nodes only.

I honour the BackColor, ForeColor and NodeFont overrides that are defined per-node. This allows you to provide a custom look for each node to reflect status.

To make like a little easier for developers I have added a new class called KryptonTreeNode that derives from the standard TreeNode class. It adds an extra property called LongText that is an extra string that will be drawn when defined to the right of the standard node text. It also includes a LongForeColor and LongNodeFont pair of overrides allowing the l0ng text to be drawn differently.

Note that apart from the KryptonTreeNode there is no new functionality in the control. It is really just a standard TreeView with some custom drawing and so any requests for new features will not be possible. It is just a TreeView!

3 Responses to “KryptonTreeView Nodes”

  1. Tom Says:

    Good to see new development is going on!

    Feature requests are not possible, but here a customdrawn request: The posibility to draw the background over the full width, to mimic the outlook treeview?!

  2. Cocotteseb Says:

    Looks really nice indeed !
    KryptonTreeNode seems to be perfect :)

    Still one question :
    1) Is this still possible with the KryptonTreeview ?
    TreeViewChannels.BackColor = KryptonManagerMain.GlobalPalette.GetBackColor1(PaletteBackStyle.PanelAlternate, PaletteState.Normal)
    TreeViewChannels.ForeColor = KryptonManagerMain.GlobalPalette.GetContentShortTextColor1(PaletteContentStyle.LabelNormalPanel, PaletteState.Normal)

    @Tom : it would be great, with the colored background it would allow us to have the treeview we can see in office 2010. So +1 for the possibility.

  3. Pradeep Says:

    Please Implement Datasource to be filled like the below:

    public static void SetDataSource(this TreeView tvw, string RootName, Object DataSource, string ValueMember, string DisplayMember, object NodeToSelect = null, Control[] ControlsToClear = null)
    {
    tvw.BeginUpdate();
    tvw.ClearDataSource(ControlsToClear);

    TreeNode root = new TreeNode(RootName) { Name = “Root” };
    tvw.Nodes.Add(root);

    CurrencyManager currencyManager = (CurrencyManager)tvw.BindingContext[DataSource];
    if (currencyManager.Count > 0)
    {
    IList innerList = currencyManager.List;

    PropertyDescriptor pdDisplay = currencyManager.GetItemProperties()[DisplayMember];
    if (pdDisplay == null) { MsgBox.Error(“Invalid Display Member: ” + DisplayMember, “Unable to set Datasource”); return; }

    PropertyDescriptor pdValue = currencyManager.GetItemProperties()[ValueMember];
    if (pdDisplay == null) { MsgBox.Error(“Invalid Value Member: ” + ValueMember, “Unable to set Datasource”); return; }

    foreach (object record in innerList)
    {
    string Text = pdDisplay.GetValue(record).ReturnEmptyIfNull();
    string Value = pdValue.GetValue(record).ReturnEmptyIfNull();

    TreeNode childNode = new TreeNode(Text) { Name = tvw.setName(Value), Tag = record };
    root.Nodes.Add(childNode);
    }
    }
    tvw.EndUpdate();
    tvw.Format();

    if (NodeToSelect != null) { tvw.SelectNode(NodeToSelect.ToString()); tvw.Focus(); }

    }

Leave a Reply