blog community

Welcome to blog community Sign in | Join | Help
in Search

Wouter van Vugt

This blog is no longer maintained and has moved

Writing to the Visual Studio 2005 OutputWindow from a Control / Designer

Currently I am developing a templated control which includes a designer. Using this templated control I am going to upgrade my WebPart so it's editable in non-edit mode( e.g. not in an EditorZone). One of the difficult things of a developing a Control Designer, is that they are a bit harder to debug than normally. Your designtime environment becomes the runtime environment for the designer. To debug a designer, you'll normally have to set Visual Studio as the startup object for the project containing the control, thus opening a new instance of Visual Studio to debug in. In this second instance of VStudio, you'll create a new web project, add your new designable control to the Toolbox and place an instance on a Page. Now the first instance of VStudio can be used to debug the second instance containing your control and designer.

However, the first instance of Visual Studio, the one in which the control + designer is being developed, is also able to startup your designer. Say you have 2 projects in your solution, a website for testing and a library for the control, when you open a page on the website, controls in the library will be available from the toolbox under a special section (this wasn't the case in Visual Studio 2003) . Which means you can drag it on your page, and thus the designer will be instantiated. (A designer surface contains instantiated objects which are transfered to code using CodeDOM when switching to the source view).  

What I really want is not full debugging support, but a way to write messages to the Visual Studio OutputWindow. When I am able to do so, the second instance of Visual Studio needn't be started to debug the designer but I can look at the OutputWindow of the instance containing my control library. A bit of strange situation, because the control designer will write messages to its hosting application, but possible non the less. First you need to obtain a reference to the running Visual Studio, the DTE object a.k.a. the root in the extensibility namespace.

EnvDTE.DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.8.0");

DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.8.0");

Next, we need to get a reference to the OutputWindow:

Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
OutputWindow oWindow = (OutputWindow) window.Object;

Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
OutputWindow oWindow = (OutputWindow) window.Object;

Finally write a message to this window:

oWindow.ActivePane.Activate();
oWindow.ActivePane.OutputString(message);

Using this code it's possible to create a tracing routine which will trace to the ASP.NET trace at runtime and to Visual Studio at designtime. In order to test this, create a new solution. Add two projects, one website, one library. Add a simple custom control to the library project. Override the Render method to write a trace message using the code below. Drag this control on a page in your website, and gaze in amazement to your OutputWindow.

Cool!

void SafeTrace(string message)
{
   
if (!base.DesignMode)
   {
       
HttpContext.Current.Trace.Write( message);
    }
   
else
   
{
        EnvDTE.
DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.8.0");
       
if(dte != null)
        {
           
Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
           
OutputWindow oWindow = (OutputWindow) window.Object;
            oWindow.ActivePane.Activate();
            oWindow.ActivePane.OutputString(message);
        }
    }
}

void SafeTrace(string message)
{
   
if (!base.DesignMode)
   {
       
HttpContext.Current.Trace.Write( message);
    }
   
else
   
{
        EnvDTE.
DTE dte = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE.8.0");
       
if(dte != null)
        {
           
Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
           
OutputWindow oWindow = (OutputWindow) window.Object;
            oWindow.ActivePane.Activate();
            oWindow.ActivePane.OutputString(message);
        }
    }
}

(edit)The strange thing here is that you're writing debug information to the same Visual Studio as the one you're developing the control in (/edit)
(edit2)This is also possible in Visual Studio 2003, just use GetActiveObject(”VisualStudio.DTE.7.1”) (/edit)

Published Wednesday, July 27, 2005 9:13 AM by wouterv
Filed under:

Comments

No Comments
Anonymous comments are disabled

This Blog

Syndication

News


Add to Technorati Favorites
Powered by Community Server, by Telligent Systems