Using WPF Windows in Visio add-ins

With the release of .NET Framework 3.0, Windows Presentation Foundation was introduced.  WPF is the new UI development environment for forms based development.

If you are not familiar with WPF you can take a look at this introduction article on MSDN.

 

Setup your Visio add-in to support WPF

All you need to do to your add-in project to support WPF is to add references to the following assemblies…

WindowsBase.dll
PresentationCore.dll
PresentationFramework.dll

image

Create a WPF Window

The Add New Item dialog for a VSTO 3.0 project filters out all WPF templates except the User Control (WPF) template.  WPF User controls can be hosted within a WinForm instance, however we want the entire window to be WPF based.  To do this we can create a new temporary WPF project in Visual Studio and then use the Add Existing Item function in our VSTO project to copy the new WPF window files.

To create a new WPF project in Visual Studio start Visual Studio and choose the WPF Application template from the New Project dialog.  Now you can use this project to create the shell for all the WPF windows you need in your Visio add-in project.

Add a new window to this project by selecting the Window (WPF) template.

image

To add this new Window to your Visio add-in, use the Add Existing Item function.

image

Browse to the location of the WPF Application project and choose the files for the WPF window that you want to add.  You will have to set the filter to “All Files” in order to see both the .xaml and the xaml.cs files.

image

image

This function will make a copy of  selected files to your Visio add-in project folder.  At this point you can open the designer and finish the layout and development of your window.  But before you use this window you will need to fix the namespace for these files that were added.

Changing the NameSpace

Because we created the WPF window in another project, the namespace is not the same as the namespace of our Visio add-in project.  You can leave it as-is but you will need to add a using statement for that namespace or explicitly define that namespace with each instance of the window you create.  To change the namespace you will need to manually change the Class attribute in the XAML and the namespace in the xaml.cs file.

image

Set properties of the WPF Window

ShowInTaskBar = false
WindowStartupLocation = CenterOwner

I generally set these properties so that my dialogs behave like the dialogs that are built-in to Visio.  For example, if you open the Options dialog for Visio from the Tools > Options menu you wil notice that a separate item does not appear on the TaskBar.  Setting the WindowStartupLocation to CenterOwner is also dependant on the Owner property of the WPF window.  See the sample code in the section below.

Show the WPF Window

To show the WPF window we need to create an instance of the window and call its ShowDialog method.  Just like the ShowDialog method of a WinForms instance, we can specify the parent window.  As you know with WinForms, to specify the parent window as the Visio application window you had to use the IWin32Window interface which wraps the HWND or Handle property.  In WPF we use the WindowInteropHelper class as shown in the code below.

 private void ShowWPFOptions()
{
    OptionsWindow window = new OptionsWindow();

    // use WindowInteropHelper to set the Owner of our WPF window to the Visio application window
    System.Windows.Interop.WindowInteropHelper hwndHelper = new System.Windows.Interop.WindowInteropHelper(window);
    hwndHelper.Owner = new IntPtr(Globals.ThisAddIn.Application.WindowHandle32);

    // show our window
    window.ShowDialog();

    // if OK was selected then do work
    if (window.DialogResult.HasValue && window.DialogResult.Value)
    {
        // do any work based on the success of the DialogResult property
    }
}
  

Sample Code

Click here to download the sample code demonstrating both the WinForms method and the WPF window method in a VSTO 3.0 based add-in project for Visio 2007…

VisioWPFSampleAddin.zip