Alessandro Del Sole's Blog

/* A programming space about Microsoft® .NET® */
posts - 159, comments - 0, trackbacks - 0

My Links

News

Your host

This is me! This space is about Microsoft® .NET® and Microsoft® Visual Basic development. Enjoy! :-)

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.

Microsoft MVP

My MVP Profile

I'm a VB!

Watch my interview in Seattle

My new book on VB 2015!

Pre-order VB 2015 Unleashed Pre-order my new book "Visual Basic 2015 Unleashed". Click for more info!

My new book on LightSwitch!

Visual Studio LightSwitch Unleashed My book "Visual Studio LightSwitch Unleashed" is available. Click the cover!

Your visits

Follow me on Twitter!

CodePlex download Download my open-source projects from CodePlex!

Article Categories

Archives

Post Categories

.NET Framework

Blogroll

Help Authoring

Microsoft & MSDN

Setup & Deployment

Visual Basic 2005/2008/2010

Using WPF custom controls in VSTO app-level solutions

As you perhaps already know, you can add WPF controls to your VSTO solutions adding an ElementHost control onto Windows Forms user controls and then setting the Child property value of the ElementHost to a desired WPF control. I wrote an article some time ago about reaching this objective and that you can find here.

 

But you are not limited to adding only WPF controls provided by the Base Class Library. In fact, you can add to your VSTO solutions even custom WPF controls and this is what I’m going to show in this post. Let’s begin by creating a new Excel Add-in solution in Visual Studio 2008 (File|New|Project|Visual Basic|Office 2007).

 

First of all, we need a custom WPF control. Let’s select the Project|Add new item command and then let’s choose the WPF User Control item template, as shown in the following picture:

 

 

Our control’s name is e.g. CompositeUserControl.xaml. This is just a demo, so we won’t need a complex control but something simple can be good to understand. We have a simple Grid, that is divided into two rows:

 

    <Grid>

        <Grid.RowDefinitions>

            <RowDefinition/>

            <RowDefinition Height="50"/>

        </Grid.RowDefinitions>

 

We could then e.g. write a text message and implement a button:

 

        <TextBlock Grid.Row="0" Text="Write something here"

                   FontWeight="Bold" FontSize="14" Name="Text1">

            <TextBlock.Foreground>

                <SolidColorBrush Color="Black" x:Name="TextBrush1"/>

            </TextBlock.Foreground>

        </TextBlock>

 

        <Button Grid.Row="1" Width="100" Height="40" Name="Button1">Click me!</Button>

    </Grid>

 

We specified a SolidColorBrush element for our TextBlock because we could enhance the UI implementing a color animation and this needs a Brush object as a target. Supposing we want to start the animation when the Grid is loaded, we could handle the Grid.Triggers as follows:

 

        <Grid.Triggers>

            <EventTrigger RoutedEvent="Grid.Loaded">

               

            <BeginStoryboard>

                <Storyboard>

                    <ColorAnimation From="Black" To="Red"

                                    AutoReverse="True" RepeatBehavior="Forever"

                                    Duration="0:0:3"

                                    Storyboard.TargetProperty="Color"

                                    Storyboard.TargetName="TextBrush1">

                    </ColorAnimation>

                </Storyboard>

            </BeginStoryboard>

            </EventTrigger>

        </Grid.Triggers>

 

 

At this point we can double click the button on the designer and Visual Studio 2008 will generate a new event handler stub for us, that we could just implement as follows:

 

    Private Sub Button1_Click(ByVal sender As System.Object, _

                              ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click

        System.Windows.MessageBox.Show("You clicked!")

    End Sub

 

As I said before, something easy just to understand how things work. Let’s build our solution, so that our new WPF user control can be available on the toolbox and recognized by the IDE.

Now let’s add a new Windows Forms user control to our project; we need this step to host our WPF user control. Let’s select the Project|Add user control command and then the User Control item template as shown in the following picture:

 

 

 

Our user control will be called HostUserControl.vb. In the toolbox, expand the WPF Interoperability tab and double click the ElementHost item, that will be added to the user control’s surface. This task will add all the necessary references to the WPF main assemblies, like WindowsBase.dll, PresentationCore.dll and PresentationFramework.dll. Click the ElementHost Tasks arrow and select the control to be hosted in the popup window, as shown in the following picture:

 

 

 

As you can see in the designer, our Windows Forms user control is currently hosting a totally working WPF control:

 

 

 

To demonstrate how we can interact with the WPF custom control items, let’s switch to the code for HostUserControl.vb and let’s write the following:

 

    Public Sub New()

 

        InitializeComponent()

 

        'I can interact in code with my WPF custom control elements if they have

        'the Name property set.

        Me.CompositeUserControl1.Text1.Text = "WPF & VSTO Demo"

    End Sub

 

We just changed at runtime a property of one UI item in our WPF custom control. Now let’s suppose we want to create a custom task pane for Microsoft Excel 2007 that will contain our user control. If you need some more informations about creating custom task panes, you can check out this article of mine in the VB Developer Center. Double click the ThisAddin.vb code file and type the following code:

 

Imports Microsoft.Office.Tools

 

 

    Private WpfTaskPane As CustomTaskPane

 

    Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup

 

        Me.WpfTaskPane = Me.CustomTaskPanes.Add(New HostUserControl, "WPF Composite Control")

        Me.WpfTaskPane.Visible = True

 

    End Sub

 

If you try to run the compiled project, you should obtain something like this:

 

 

 

You should see the text message’s foreground color change intermittently from black to red. Cool! J

So it’s quite easy integrating WPF custom controls in VSTO solutions, extending what we already knew about WPF base controls. You can download the code from here.

 

Alessandro

Print | posted on sabato 10 gennaio 2009 14:49 | Filed Under [ Visual Studio Tools for Office ]

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 5 and 1 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET