Robert Dodd
Robert Dodd

Reputation: 2187

Dynamically creating objects at runtime that inherit from a base class

I am writing a game editor, and have a lot of different "tool" objects. They all inherit from BTool and have the same constructor.

I would like to dynamically populate a toolbox at runtime with buttons that correspond to these tools, and when clicked have them create an instance of that tool and set it as the current tool.

Is this possible, and if so will it be better/easier than creating those buttons by hand?

Upvotes: 2

Views: 3082

Answers (3)

mmr
mmr

Reputation: 14919

You will have to instantiate each object.

However, you can then implement a 'clicked' method for a set of buttons, something like:

List<BTool> theTools = new List<BTool>();
BTool mapTool1 = new MapTool1(); //assumes that MapTool1 inherits from BTool
BTool mapTool2 = new MapTool2(); 
//and so on

If you're using WPF or WinForms, the exact code will be slightly different. Assuming you're using WPF, you'll do something like this in the xaml:

<StackPanel Name="ToolButtons" /> //make sure to orient your tools how you like, vertical or horizontal

and then in the constructor of the WPF form:

foreach (BTool b in theTools){
   Button button = new Button();
   button.Title = b.Name; //or .ToString, whatever
   button.Clicked += b.ClickedEvent; //where ClickedEvent is a method in BTool that implements the interface for the Clicked event
   ToolButtons.Children.Add(button);
}

Upvotes: 0

Josh
Josh

Reputation: 69262

If you're using .NET 3.5, I'd go check out MEF (Managed Extensibility Framework) and if you're using .NET 4.0 then MEF is already built in.

In a nutshell, this is all you would have to do. (Plus of course some simple code to "kick off" the composition. It's all on the MEF site linked above.)

[InheritedExport]
public abstract class BTool {
}

public class HandTool : BTool {
}

public class LassoTool : BTool {
}

public class Game {

    [ImportMany]
    public List<BTool> Tools {
        get;
        set;
    }

}

Upvotes: 4

SLaks
SLaks

Reputation: 887365

Yes.

To find the tools, you can call Assembly.GetTypes:

var toolTypes = typeof(Tool).Assembly.GetTypes()
    .Where(t => typeof(Tool).IsAssignableFrom(t))
    .ToArray();

To create the tools, you can call Activator.CreateInstance:

obj = Activator.CreateInstance(type, arg1, arg2);

Upvotes: 4

Related Questions