Create 'open tool pane' link in ASP.NET 2.0 Web Parts for SharePoint

I was recently asked how one could include the 'open tool pane' link in an ASP.NET Web Part hosted in SharePoint.  One can see an example of this in the Content Editor Web Part and several others that are offered OOB with SharePoint.  The purpose is to provide the user a link to quickly edit the properties of the web part initially by opening the editor zone in SharePoint.  The same functionality is provided when the page is put in 'Edit' mode and the user selects the web part 'Edit' menu and selects the 'Modify this Web Part' link. 

WSS v3 Web Parts, which are derived from the Microsoft.SharePoint.WebParts.WebPart class, make this simple by providing the capability to leverage the ToolPane.GetShowExtensibleToolPaneEvent.  This will return the javascript required to perform the required action.  Since this is a static reference my first reaction was to put add a reference to the Microsoft.SharePoint namespace in my project and use this code in my ASP.NET web part.  It turns out that the first parameter expected by this method is a Microsoft.SharePoint.WebParts.WebPart object.  Even though it derives from the System.Web.UI.WebControls.WebParts.WebPart object you can't pass the ASP.NET 2.0 web part as a parameter.  This will create a compile time error.

The next step was to leverage the generated javascript code in the ASP.NET 2.0 web part and it should work, right?  Not so fast.  The javascript that is produced for the Content Editor Web Part is shown below.  You can figure this out by right clicking the 'open tool part' link and selecting properties.

 javascript:MSOTlPn_ShowToolPane2Wrapper( ‘Edit’, ‘129’, ‘g_59b79f76_b13b_42aa_85f2_f2f1c2ba71f1’);

So we generate the href reference to MSOTlPn_ShowToolPane2Wrapper and pass the parameters; 'Edit', '129' and 'g_59b79f76_b13b_42aa_85f2_f2f1c2ba71f1'. What do those parameters mean? The first is the display mode for the editor pane, the second we'll get to, and the third took a little work. To figure out the second and third I built a web part that output everything that had an ID associated with it; ID, ClientID, etc. Turns out the third variable is just the ID property of the Web Part. One down, one to go.

The second parameter took some more digging and was the bane of my existence for a few hours. I tried several other ID type properties here and nothing worked. I added the web part to a new page so to see if there was a difference in sites (SPWeb) that was generating the ID. Nothing so far. I decided to hook up Fiddler to see what was going on behind the scenes. After all, we have the 'Modify this Web Part' link that does the same thing I wanted to do. After running Fiddler I clicked 'Edit' > 'Modify this Web Part' and looked through the results. Using the known Content Editor Web Part I was able to track down the mysterious '129' parameter. Is was passed in the request as the MSOWebPartPage PostBackSource value. That didn't help much, but I did know where to look now in my custom web part to find the value I needed to pass. Turns out my MSOWebPartPage PostBackSource value was '16'. So I changed the link to be

 literal.Text = "<a href=\"javascript:MSOTlPn_ShowToolPane2Wrapper('Edit', '16', '" + this.ID + "')\">open tool pane</a>";

and it worked. Now I just need to find a property with 16 as the value, however, this didn't exist. I turned on the debugger and looked, and looked, and...well, nothing. What is this value? I checked the Web Part Gallery for the site collection to see of maybe the reference was generated there, but my Web part Gallery Id was 88. No luck. The ID for this parameter is being generated somewhere, by something, in order to create the 'Modify this Web Part' menu item. It turns out that you can just pass a reference to 'this' in order to have SharePoint know the post back source. So after changing the code to

 literal.Text = "<a href=\"javascript:MSOTlPn_ShowToolPane2Wrapper('Edit', this, '" + this.ID + "')\">open tool pane</a>";

things worked like a charm.  There are issues with this implementation.  The SharePoint team could decide to change the javascript signature or remove the javascript altogether.  In the meantime, this accomplishes the goal and gives the ASP.NET web part SharePoint type functionality.