views:

45

answers:

4

I have developed a generic TreeList control in C# which combines a TreeView with a ListView to obtain a multi-column TreeView.

I would like to use a TreeView derived class for the TreeView portion of the control, but keep the TreeListView control generic.

In my TreeListView I have a member variable:

protected TreeView treeView;

and the InitializeComponent function creates the treeView:

private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.listView = new System.Windows.Forms.ListView(); this.treeView = new System.Windows.Forms.TreeView();

So if I have a derived TreeView class called MyTreeView, is there any way in which I could get InitializeComponent to do something like:

this.treeView = new MyTreeView() but somehow specifying the type of class to instantiate at runtime, e.g. this.treeView = new (typeof(type specified in constructor)?

+2  A: 

No, the InitializeComponent is an automatically-generated method and any changes you make will be reverted when you modify with the designer (well, who knows when). You can't control the code generation in the way that you want.

You should leave InitializeComponent as-is, and create the object for treeView afterwards, in your constructor, programatically.

Hope that helps.

Kieren Johnstone
Will this not cause issues with the control being added in the 'wrong' order into the ControlCollection?
The Nybbler
I can't think why - nothing should refer to a control by its index in a collection
Kieren Johnstone
So should I create a derived TreeListView class, e.g. MyTreeListView that removes the default TreeView object and replaces it with a MyTreeView object? Will this work?
The Nybbler
If you are always going to replace the TreeView, I can't see why you'd keep it in the first place. You could just have a private member `private TreeView treeView;` in the class, and then in your constructor create it: `treeView = new MyTreeView();` (then add it to the controls collection, set a `Dock`, etc.).
Kieren Johnstone
No the point is I want to keep a generic TreeListView that just works with a standard TreeView and then have specialized ones which use a sub-classed TreeView e.g. MyTreeView.
The Nybbler
Aha, then I would suggest a generic class, if you are using C# 2 or above: `public class TreeViewList<T> where T : TreeView` and then `private T treeView;` and in the constructor, `this.treeView = new T()`. Does that make sense? (http://msdn.microsoft.com/en-us/library/512aeb7t.aspx)
Kieren Johnstone
That sounds like the type of thing I need but will this work with the built in VS designer? At the moment it is instantiated in InitializeComponent and sets a number of properties automatically. It would be useful if the TreeView could continue to be viewed in the designer but not absolutely essential.
The Nybbler
A: 

this.treeView = new (typeof(type specified in constructor)

To create an instance of a class at runtime, use:

MyObject obj = Activator.CreateInstance(myType);
slugster
That would work, but would depend on modifying the Visual Studio code generator to generate the code desired, when the alternative is a simple `new` statement in the constructor.. ?
Kieren Johnstone
A: 

Use the designer to drag and drop a standard control (I often use a Panel for this). In the properties of the control, set the name to something you recognise.

Next, open the Form.Designer.cs file (assuming you're in VS2005 or above) and search through the text for the definition of the control instance. Change the type from Panel to your control type, then search for the instantiation of the control and change from New Panel() to new Treeview().

After saving, compile the code and open the designer -- your panel will change into your tree control and you can continue as normal. This change will persist if you come back and change the form through the designer. I do this a lot in my current projects because we have slightly different control versions for different customers so as can't add them all to the toolbox.

Dr Herbie
A: 

The issue is that I want to keep a generic version of my TreeList control but I also want a specialised version that will use a derived TreeView control within it.

I want to be able to do this without having to modify the generic version of the TreeList control.

The Nybbler