The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








Latest Diggs - Programming

Internet Blogs - Blog Top Sites

Site Hits

Total: 2,551,710
since: 19 Jan 2005

You got peanut butter in my chocolate! - Hosting XAML Controls in Windows Forms

posted Tue 07 Mar 06

XAML is an incredibly powerful language, as is the WPF engine that is responsible for rendering it. However, all that 2D and 3D flexibility comes at a price. There are times when you want some of the functionality of Windows Forms that is either too tedious or nearly impossible to create (for a practical cost) within WPF/XAML, such as MDI windows, non-modal dialogs that belong to a parent window, tabbed dialog controls, etc.

To give your applications the structure of a Windows Forms application but selective ability to host XAML user controls within the confines of a Windows Form (chocolate in the peanut butter!), you can make use of a control called ElementHost that you find in the WindowsFormsIntegration.dll Assembly. Here's the rub: if you follow some of the MSDN documentation, you will be told to find this in the Reference Assemblies\Microsoft\WPF\v3.0 directory. If you do that, and you're running the February CTP - you will get a strong name validation failure and you won't be able to create WPF/WinForms interop applications.

The first step in creating a XAML-hosting WinForms application is to create the XAML. To do this, just use VS 2005 (assuming you've installed the VS extensions) to create a new XAML Custom Control Library called AvalonControls in a solution called AvalonInWinForms. Set the XAML for UserControl1.xaml to the following (this looks very similar to the MSDN sample - except this XAML actually compiles!!):

<UserControl x:Class="AvalonControls.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
  <Grid>
    <!-- Place a Label control at the top of the view. -->
    <Label
      HorizontalAlignment="Center"
      TextBlock.TextAlignment="Center"
      FontSize="20"
      Foreground="Red"
      Content="Model: Cone"/>
    <!-- Viewport3D is the rendering surface. -->
    <Viewport3D Name="myViewport" >
      <!-- Add a camera. -->
      <Viewport3D.Camera>
        <PerspectiveCamera
          FarPlaneDistance="20"
          LookDirection="0,0,1"
          UpDirection="0,1,0"
          NearPlaneDistance="1"
          Position="0,0,-3"
          FieldOfView="45" />
      </Viewport3D.Camera>
      <!-- Add models. -->
    
        <ModelVisual3D>
          <ModelVisual3D.Content>
            <Model3DGroup >
             
                <!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
                <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
                <!-- Define a red cone. -->
                <GeometryModel3D>
                  <GeometryModel3D.Geometry>
                    <MeshGeometry3D
  Positions="0.293893 -0.5 0.404509  0.475528 -0.5 0.154509  0 0.5 0  0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 0.154509  0.475528 -0.5 -0.154509  0 0.5 0  0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 -0.154509  0.293893 -0.5 -0.404509  0 0.5 0  0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  0.293893 -0.5 -0.404509  0 -0.5 -0.5  0 0.5 0  0 -0.5 -0.5  0 0.5 0  0 0.5 0  0 -0.5 -0.5  -0.293893 -0.5 -0.404509  0 0.5 0  -0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  -0.293893 -0.5 -0.404509  -0.475528 -0.5 -0.154509  0 0.5 0  -0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 -0.154509  -0.475528 -0.5 0.154509  0 0.5 0  -0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 0.154509  -0.293892 -0.5 0.404509  0 0.5 0  -0.293892 -0.5 0.404509  0 0.5 0  0 0.5 0  -0.293892 -0.5 0.404509  0 -0.5 0.5  0 0.5 0  0 -0.5 0.5  0 0.5 0  0 0.5 0  0 -0.5 0.5  0.293893 -0.5 0.404509  0 0.5 0  0.293893 -0.5 0.404509  0 0.5 0  0 0.5 0  "
  Normals="0.7236065,0.4472139,0.5257313  0.2763934,0.4472138,0.8506507  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  -0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.5308242,0.4294462,0.7306172  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.7236065,0.4472139,0.5257313  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.858892,0.429446,0.279071  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.8944269,0.4472139,0  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.858892,0.429446,-0.279071  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.7236065,0.4472139,-0.5257313  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.5308242,0.4294462,-0.7306172  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.2763934,0.4472138,-0.8506507  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.5308249,0.4294459,-0.7306169  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.7236068,0.4472141,-0.5257306  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8588922,0.4294461,-0.27907  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8944269,0.4472139,0  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.858892,0.429446,0.279071  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.7236065,0.4472139,0.5257313  0.858892,0.429446,0.279071  0.7236065,0.4472139,0.5257313  0.5308242,0.4294462,0.7306172  0.858892,0.429446,0.279071  "                   TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
                  </GeometryModel3D.Geometry>
                  <GeometryModel3D.Material>
                    <DiffuseMaterial>
                      <DiffuseMaterial.Brush>
                        <SolidColorBrush
                          Color="Red"
                          Opacity="1.0"/>
                      </DiffuseMaterial.Brush>
                    </DiffuseMaterial>
                  </GeometryModel3D.Material>
                </GeometryModel3D>
              
            </Model3DGroup>
          </ModelVisual3D.Content>
        </ModelVisual3D>
      
    </Viewport3D>
  </Grid>
</UserControl>

Go ahead and build that library and then add a WinForms application to your solution called WinFormsApp. Add references to PresentationCore, PresentationFramework, AvalonControls, and WindowsFormsIntegration (the location was mentioned earlier).

Double-click the main form and add the following code to the "Loaded" event handler:

private void Form1_Load(object sender, EventArgs e)
{
    ElementHost eh = new ElementHost();
    eh.Top = 30;
    eh.Left = 1;
    eh.Width = this.Width - 10;
    eh.Height = this.Width - 10;
    // this is bugged - control won't show up until form resizes
    //eh.Dock = DockStyle.Fill;
    AvalonControls.UserControl1 uc1 = new AvalonControls.UserControl1();
    eh.Controls.Add(uc1);
    eh.Show();
    this.Controls.Add(eh);
    this.Refresh();
}

Here's another thing that frustrates me: If you follow the samples and just set the ElementHost's Dock property to DockStyle.Fill, your control won't render until you manually resize the window, maximize it, or minimize it. This is because it needs to have the size changed in order to render. I'm not sure if this is a bug (I hope its a bug, because its darned annoying). To get around that, I just manually set the size of the ElementHost to a size big enough to hold the WPF-rendered user control.

Keep in mind that there's currently no visual designer for XAML user controls.. So I'd create a page out of pure XAML with a good designer and then convert that into a User Control later. Here's a screenshot of what the MSDN sample would look like if it actually compiled (yeah, I know...but the docs say they're current to Feb CTP , and they should be accurate...either leave the documentation offline, or make sure what you put online is accurate!):

There you have it, chocolate inside your peanut butter. If you prefer peanut butter inside your chocolate, you can do the opposite and host Windows Forms controls within XAML, which also has its own unique blend of handy features. There are so many options when working with WinForms 2.0 and WPF that the real hard part is figuring out which tool is right for the job.

- The .NET Addict

tags:                      

links: digg this    del.icio.us    technorati    reddit




Tag Related Posts

MobileMe vs. Live Mesh Throwdown - Round 1

Wed 16 Jul 08 10:33 A GMT-05

Building Model Classes in C# and Cocoa

Sun 15 Jun 08 3:13 P GMT-05
tags:            

NYC SharePoint Developer Needed

Mon 12 May 08 12:09 P GMT-05

CLINQ v1.1.0.0 Released!

Fri 02 May 08 5:38 P GMT-05
tags:          

iPhone Underrated as a Gaming Device?

Fri 14 Mar 08 1:50 P GMT-05
tags:        

One Framework to Rule them All

Mon 25 Feb 08 6:49 P GMT-05

CLINQ v1 Demo - Network Message Filtering

Wed 09 Jan 08 7:47 P GMT-05
tags:        

Building a Ledger Style for WPF Grids

Tue 21 Aug 07 3:30 P GMT-05
tags:    

Continuous LINQ - Can I write games with it?

Mon 13 Aug 07 3:09 P GMT-05
tags:        

My 2008 Wishlist : A Transformers MMORPG

Tue 26 Jun 07 12:04 P GMT-05
tags:        

The dreaded language bleed-over has begun

Tue 19 Jun 07 6:23 P GMT-05
tags:        

My first "Acropolis" Application

Mon 04 Jun 07 1:40 P GMT-05
tags:      

Exploring the Delegate Design Pattern

Mon 14 May 07 6:30 P GMT-05

Core Data - Almost too Easy?

Wed 18 Apr 07 2:23 P GMT-05

Will Silverlight be DOA?

Mon 16 Apr 07 8:02 P GMT-05

Exploring the MVC Pattern in WPF

Tue 10 Apr 07 12:51 P GMT-05
tags:                      

My Little Pony .NET Unleashed 2007

Fri 30 Mar 07 1:59 P GMT-05

An experience with the Leopard beta

Mon 26 Mar 07 7:45 P GMT-05
tags:                

Authorness

Thu 15 Mar 07 1:44 P GMT-05

WPF Bindings == WTF Bindings?

Mon 12 Mar 07 6:31 P GMT-05

On MUDs

Thu 08 Mar 07 5:00 A GMT-05
tags:                    

Cocoa Programming vs. WPF : NIB vs XAML

Tue 20 Feb 07 2:09 P GMT-05

Cocoa Bindings vs. WPF Binding

Thu 15 Feb 07 5:41 P GMT-05
tags:                

Ulysses Agenda Makes Redmond Developer News

Wed 29 Nov 06 7:10 P GMT-05
tags:                

Is the continuous beta the new model for Vista?

Tue 21 Nov 06 8:51 P GMT-05
tags:              

A visit to Nintendo World on "Wii Day"

Mon 20 Nov 06 12:37 P GMT-05
tags:          

Ulysses Agenda - Network Engine Test 1

Mon 09 Oct 06 2:26 A GMT-05
tags: