Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding collection of custom classes to TreeView

I'm trying to determine the best way to accomplish binding a Collection of a custom class to a TreeView.

I currently have two custom classes, one held in a Collection, and one held in a Collection inside the first class:

Collection<Device> _devices = new Collection<Device>();

class Device
{
    public ulong DeviceID { get; private set; }

    private List<Capability> _capabilities = new List<Capability>();

    public string FriendlyName{ get; set; }

    public Capability AddCapability(Capability capability)
    {
        _capabilities.Add(capability);
        return capability;
    }

   public List<Capability> GetCapabilities()
   {
       // not safe yet
       return _capabilities;
   }
}

abstract class Capability
{
    public uint CapabilityIndex { get; private set; }
    public string FriendlyName{ get; set; }
}

I'm trying to get a TreeView to display the collection of devices which when expanded lists the capabilities.

Options I've considered include:

  • looping through and creating TreeNode objects from the data I want to display (but I'm not sure how is best to refer back to the original object when selected)
  • inheriting from the TreeNode class but this feels ugly as I'm storing the same data in multiple places (and most of the time I don't need them as TreeNodes so it feels like a waste of resources)

Any suggestions?

like image 593
Graham Wager Avatar asked Jan 16 '23 03:01

Graham Wager


1 Answers

When dealing with a TreeView, I usually end up generating a wrapper class that inherits from TreeNode and which holds the actual object that I'm displaying as the node. That way I can bind to the TreeView, get the heirarchy I need, and my business classes don't actually have to subclass a UI component. It works nicely when handling the TreeView events as well, because you can just inspect the node for its type and different typed nodes can be handled differently - display a different UI or whatever.

private class FooNode : TreeNode
{
    public FooNode(Foo foo)
    {
        this.Text = foo.ToString(); //Or FriendlyName
        this.Foo = foo;
        this.Foo.Bars.ForEach(x => this.Nodes.Add(new BarNode(x)));
    }

    public Foo Foo
    {
        get;
        private set;
    }
}

private class BarNode : TreeNode
{
    public BarNode(Bar bar)
    {
        this.Text = bar.ToString(); //Or FriendlyName
        this.Bar = bar;
    }

    public Bar Bar
    {
        get;
        private set;
    }
}

This example may be exactly what you mean by your second option. In that case, I vote for the second option!

like image 71
C B Avatar answered Jan 20 '23 12:01

C B