Wednesday, December 28, 2005

User Control in Tool Window of a Visual Studio Addin

Visual Studio .NET 2005 offers some new APIs for making it easier to host a managed add-in. For instance, the function CreateToolWindow2() allows hosting a custom control within a tool window. A shim control is no longer necessary. The function call might look like this:
_toolWindow = toolWins.CreateToolWindow2(
   _addInInstance,
   asmPath,
   ctlProgId,
   "AgileTest",
   guidString,
   ref objTemp);
The documentation states that the objTemp parameter will contain a reference to the user control hosted in the new tool window. With my experiments so far I have never found that variable to be anything other than null. In order to get a reference to my hosted user control I therefore used a different approach. First I defined an event on the class level for the user control like this:
public static event EventHandler ControlCreated;

private void AgileTestHostCtrl_Load(object sender, EventArgs e) {
   if(ControlCreated != null) {
      ControlCreated(this, null);
   }
}
For this event I defined an event handler in the Connect class of the add-in:
void AgileTestCtrl_ControlCreated(object sender, EventArgs e) {
   _hostedControl = (AgileTestCtrl)sender;
}
Registering the handler on a class level event is easy:
AgileTestCtrls.AgileTestCtrl.ControlCreated += 
   new EventHandler(AgileTestCtrl_ControlCreated);
Now when the user control is loaded the event is fired, and the event handler is called. The limitation of this solution is obviously that should you need several instances of the same tool window it might get more complicated to distinguish between them. One option to solve this might be to use an event that carries additional information in its properties. In my case as I don't need more than one instance of the tool window and hence of my user control, this solution works fine and reliable. Please drop me a note if you are aware of a better solution. Thank you!

1 comments:

Mike said...

You could also tag you UserControl class with the class attribute [ComVisible(true)] and the reference will no longer be null

Post a Comment

All comments, questions and other feedback is much appreciated. Thank you!