ActiveX Controls in WPF?

(Tunes I'm listening to while blogging: Style Council - "Home & Abroad")

You betcha!  You can certainly host ActiveX controls in a WPF application.  You do this by using Windows Forms - WPF Integration.  Okay, from now on, I'm gonna refer to this as "Crossbow" because that is our internal code name for this technology and I'm really getting tired of saying "Windows Forms - WPF Integration".  Now...you can host ActiveX control in a WPF application because Windows Forms already supports hosting ActiveX controls and since Crossbow enables WPF applications to host Windows Forms controls you can use this technique to subsequently host ActiveX controls, whew!  So how do we do it specifically?  Let's build a little sample to do this...

Here are the steps:

1) Launch VS and create a new "Avalon Application"  (Yeah, I know the templates still refer to Avalon...)

2) Let's add another project type to this solution, specifically a Windows Control Library project

3) Now what the UserControl in design mode, make sure your Toolbox is visible and right-click anywhere on the Toolbox and choose "Choose Items..."

This will give us a change to add the ActiveX control of our choice to the Toolbox so we can use it in our UserControl.  This operation will also generate the managed wrappers for our ActiveX control.  In this specific example, I will use the Adobe Acrobat Reader ActiveX control.

This will now give us an item on our Toolbox for the Adobe Acrobat Reader control so we can place it on our UserControl design surface.

5) Select the Adobe Acrobat Reader control on the Toolbox

6) And place it on the UserControl design surface

7) Now lets make sure to set the Dock property of the control to DockStyle.Fill so the control will always take up all the real estate of the UserControl.

8) Okay, now let's add a method to our UserControl that will allow us to load a PDF file.  We'll do this by just creating a public method on the UserControl and in the implementation we will just call into the underlying ActiveX control's LoadFile() method.

namespace

WindowsControlLibrary1
{
       public partial class UserControl1 : UserControl
{
              public UserControl1()
{
InitializeComponent();
}
              public void Load(string File)
{
                     this.axAcroPDF1.LoadFile(File);
}
}
}

9) Now let's go to the Window1.xaml file in the XML editor and add a handler for the Loaded event and give the grid tag a name

<

Window x:Class="AvalonApplication21.Window1"
xmlns="https://schemas.microsoft.com/winfx/avalon/2005"
xmlns:x="https://schemas.microsoft.com/winfx/xaml/2005"
Title="AvalonApplication21"
Loaded="WindowLoaded"
>
<Grid x:Name="grid1">

</Grid>
</Window>

10) Jump over to the Window1.xaml.cs file and uncomment the WindowLoaded event handler and add the following implementation:

private void WindowLoaded(object sender, RoutedEventArgs e)
{
       WindowsFormsHost host = new WindowsFormsHost();
WindowsControlLibrary1.UserControl1 uc1 = new WindowsControlLibrary1.UserControl1();
host.Children.Add(uc1);
       this.grid1.Children.Add(host);
uc1.Load("C:\\ribs.pdf");
}

The above code will instantiate a WindowsFormsHost control and an instance of the UserControl (that contains the ActiveX control), then it will add the UserControl to the WindowsFormsHost control and then add the WindowsFormsHost control as a child of the Grid tag in our XAML.  Finally it will call our Load method which will populate the Acrobat reader control with a PDF document.

11) Okay, run it!

WOO HOO!  We did it!  Now go get a beer or something...