Dynamically creating objects at runtime that inherit from the base class
I am writing a game editor and have many different "tool" objects. They all inherit from BTool and share the same constructor.
I would like to dynamically populate a toolbar at runtime with buttons corresponding to these tools, and when clicked, they instantiate that tool and set it as the current tool.
Is this possible, and if so it would be better / easier than creating these buttons manually?
a source to share
Yes.
To find tools, you can call Assembly.GetTypes
:
var toolTypes = typeof(Tool).Assembly.GetTypes()
.Where(t => typeof(Tool).IsAssignableFrom(t))
.ToArray();
To create tools, you can call Activator.CreateInstance
:
obj = Activator.CreateInstance(type, arg1, arg2);
a source to share
If you are using .NET 3.5 I would look at MEF ( Managed Extensibility Framework ) and if you are using .NET 4.0 then MEF is already built in.
In short, this is all you need to do. (Plus, of course, some simple code to "run" 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;
}
}
a source to share
You will need to create an instance of each object.
However, then you can implement the 'clicked' method for the set of buttons, for example:
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 are using WPF or WinForms, the exact code will be slightly different. Assuming you are using WPF, you would do something like this in your xaml:
<StackPanel Name="ToolButtons" /> //make sure to orient your tools how you like, vertical or horizontal
and then in the WPF form constructor:
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);
}
a source to share