1

Is there anyway to subclass a Winforms Treeview to display root node ascendants expanding nodes upwards? The following photoshopped image illustrates the desired result:

Standard and reverse Winforms TreeView controls

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Matias Masso
  • 1,670
  • 3
  • 18
  • 28
  • You can create such UI in WPF (With nodes at bottom). Take a look at [this post](https://social.msdn.microsoft.com/Forums/vstudio/en-US/b7fe9a1a-c8c6-45fb-a2bf-42233b20fe41/treeview-upside-down). – Reza Aghaei Dec 18 '18 at 15:59
  • Thanks Reza but I need to use it on traditional Winforms projects – Matias Masso Dec 18 '18 at 16:33
  • You can host a WPF control in Windows Forms, using an [`ElementHost`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.integration.elementhost?view=netframework-4.7.2) control. You can see an [example](https://stackoverflow.com/a/51662516/3110834) which shows you to create a Windows Forms user control which hosts a WPF control. – Reza Aghaei Dec 18 '18 at 16:39

1 Answers1

1

As an option, you can rely on an ElementHost Windows Forms control to host a WPF TreeView control in it. Then for the WPF TreeView and its nodes, set RotateTransform to 180 degrees.

Example

In the following example I've created a Windows Forms UserControl containing an ElementHost to host a WPF TreeView control and by setting a 180 degree RotateTransform for the tree and its nodes, I'm making an upside down (a bottom up) tree:

enter image description here

Here is the code. Just add the code as a class in your application and make sure you have already added required assemblies which are mentioned at the end of the post. Then build the project and drop an instance of MyTreeView on your form.

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.Windows.Media;
public class MyTreeView : System.Windows.Forms.UserControl, ISupportInitialize
{
    private ElementHost elementHost = new ElementHost();
    private TreeView tree;
    private System.Windows.Forms.TreeView winFormsTree;
    public MyTreeView()
    {
        tree = new TreeView();
        winFormsTree = new System.Windows.Forms.TreeView();
        Nodes = winFormsTree.Nodes;
        tree.LayoutTransform = new RotateTransform(180);
        tree.FlowDirection = FlowDirection.RightToLeft;
        elementHost.Dock = System.Windows.Forms.DockStyle.Fill;
        elementHost.Name = "elementHost";
        elementHost.Child = tree;
        Controls.Add(elementHost);
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public System.Windows.Forms.TreeNodeCollection Nodes { get; }
    public void BeginInit() { }
    public void RefreshTree()
    {
        tree.Items.Clear();
        RefreshTree(tree.Items, Nodes);
    }
    private void RefreshTree(ItemCollection items, 
        System.Windows.Forms.TreeNodeCollection nodes)
    {
        foreach (System.Windows.Forms.TreeNode node in nodes)
        {
            var item = new TreeViewItem();
            var label = new Label();
            label.LayoutTransform = new RotateTransform(180);
            label.Content = node.Text;
            label.Padding = new Thickness(0);
            item.Header = label;
            items.Add(item);
            RefreshTree(item.Items, node.Nodes);
        }
    }
    public void EndInit()
    {
        RefreshTree();
    }
    protected override void Dispose(bool disposing)
    {
        if (disposing && winFormsTree != null)
            winFormsTree.Dispose();
        base.Dispose(disposing);
    }
}

Referenced Assemblies

Here are required referenced assemblies: PresentationCore, PresentationFramework, WindowsBase, WindowsFormsIntegration.

Note

For this example, I used a TreeNodeCollection. You can use any other structure which you like. You can add nodes in design mode using the Nodes property and see the tree at run-time. As a known issue for this example, the changed that you make in Nodes property will not reflect immediately at design-time, but are serialized and will be shown at run-time.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398