Windows Forms Integration


Instead of rewriting your user interface completely from scratch for WPF, you can use existing Windows Forms controls within WPF applications, and create new WPF controls to be used within Windows Forms applications. The best way of integrating Windows Forms and WPF is by creating controls and integrating the controls in the application types of the other technology.

Important 

The integration of Windows Forms and WPF has a big drawback. If you integrate Windows Forms with WPF, the Windows Forms controls still look like they looked in the old days. Windows Forms controls and applications don’t get the new look of WPF. From a user interface standpoint, it would be better to rewrite the UI completely.

Tip 

To integrate Windows Forms and WPF, you need classes from the namespace System.Windows.Forms.Integration in the assembly WindowsFormsIntegration.

WPF Controls within Windows Forms

You can use WPF controls within a Windows Forms application. AWPF element is a normal .NET class. However, you cannot use it directly from the Windows Forms code; a WPF control is not a Windows Forms control. The integration can be done by the wrapper class ElementHost from the namespace System .Windows.Forms.Integration. ElementHost is a Windows Forms control, as it derives from System.Windows.Forms.Control, and can be used like any other Windows Forms control in a Windows Forms application. ElementHost hosts and manages WPF controls.

Let’s start with a simple WPF control. With the .NET Framework 3.0 extensions for Visual Studio, you can create a Custom Control Library (WPF). The sample control is derived from the base class UserControl and contains a grid and a button with a custom content.

  <UserControl x:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >     <Grid>       <Button>         <Canvas Height="230" Width="230">           <Ellipse Canvas.Left="50" Canvas.Top="50" Width="100" Height="100"               Stroke="Blue" StrokeThickness="4" Fill="Yellow" />           <Ellipse Canvas.Left="60" Canvas.Top="65" Width="25" Height="25"               Stroke="Blue" StrokeThickness="3" Fill="White" />           <Ellipse Canvas.Left="70" Canvas.Top="75" Width="5" Height="5" Fill="Black" />           <Path Name="mouth" Stroke="Blue" StrokeThickness="4"               Data="M 62,125 Q 95,122 102,108" />           <Line X1="124" X2="132" Y1="144" Y2="166" Stroke="Blue" StrokeThickness="4" />           <Line X1="114" X2="133" Y1="169" Y2="166" Stroke="Blue" StrokeThickness="4" />           <Line X1="92" X2="82" Y1="146" Y2="168" Stroke="Blue" StrokeThickness="4" />           <Line X1="68" X2="83" Y1="160" Y2="168" Stroke="Blue" StrokeThickness="4" />          </Canvas>        </Button>      </Grid>  </UserControl> 

You can create a Windows Forms application by selecting the Windows Forms application template. In this project, you have to reference the assemblies PresentationCore, PresentationFramework, WindowsBase, WindowsFormsIntegration, and of course the assembly containing the WPF control. Now, you can create an instance of the class ElementHost and set the Child property to a new instance of the WPF control. The ElementHost instance is added to the Controls collection of the Form just like a Windows Forms control. The controls just don’t show up in the toolbox, so you have to do this manually. In the constructor of the Form1 class a traditional Windows Forms Button is created and added to the form as well:

  using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Windows.Forms.Integration; namespace Wrox.ProCSharp.WPF {     public partial class Form1 : Form     {         private ElementHost eltHost = new ElementHost();         public Form1()         {             InitializeComponent();             // add a WPF control             WPFControl.UserControl1 uc = new WPFControl.UserControl1();             eltHost.Child = uc;             eltHost.Width = 230;             eltHost.Height = 230;             this.Controls.Add(eltHost);             // add a Windows Forms control             Button winFormsButton = new Button();             winFormsButton.Text = "Click Me!";             winFormsButton.Width = 100;             winFormsButton.Height = 100;             winFormsButton.Top = 250;             winFormsButton.Left = 40;             this.Controls.Add(winFormsButton);         }     } } 

Starting the Windows Forms application, you can see both the WPF control as well the Windows Forms control inside one form, as shown in Figure 31-46.

image from book
Figure 31-46

Of course, you can add methods, properties, and events to the WPF control and use them in the same way as with other controls.

Windows Forms Controls within WPF Applications

You can integrate Windows Forms and WPF in the other direction as well: placing a Windows Forms control within a WPF application. As with the ElementHost class used to host a WPF control inside Windows Forms, now you need a wrapper that is a WPF control to host a Windows Forms control. This class has the name WindowsFormsHost and is in the same assembly, WindowsFormsIntegration. The class WindowsFormsHost is derived from the base classes HwndHost and FrameworkElement, and thus can be used as a WPF element.

For this integration, a Windows Control Library is created first. Add a TextBox and Button control to the form by using the Designer. To change the Text property of the button, the property ButtonText is added to the code behind:

  public partial class UserControl1 : UserControl {    public UserControl1()    {       InitializeComponent();    }    public string ButtonText    {       get { return button1.Text; }       set { button1.Text = value; }    } } 

In the WPF application, you have to reference the assemblies WindowsFormsIntegration, System .Windows.Forms, and the assembly of the Windows Forms control. To use the Windows Forms control from XAML, you must add a XML namespace alias to reference the .NET namespace. Because the assembly containing the Windows Forms control is in a different assembly from the WPF application, you also must add the assembly name to the namespace alias. The Windows Forms control can now be contained within a WindowsFormsHost element as shown. You can assign a value for the property ButtonText directly from XAML similarly to .NET Framework elements.

 <Window x:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:wf="clr-namespace:Wrox.ProCSharp.WPF;assembly=WindowsFormsControl"     Title="WPF Interop Application" Height="300" Width="300"     >     <Grid>       <Grid.RowDefinitions>         <RowDefinition />         <RowDefinition />       </Grid.RowDefinitions>       <WindowsFormsHost Grid.Row="0" Height="180">         <wf:UserControl1 x:Name="myControl" ButtonText="Click Me!" />       </WindowsFormsHost>       <StackPanel  Grid.Row="1">          <TextBox Margin="5,5,5,5" Width="140" Height="30"></TextBox>         <Button Margin="5,5,5,5" Width="80" Height="40">WPF Button</Button>       </StackPanel>     </Grid> </Window>

You can see a view of the WPF application in Figure 31-47. Of course, the Windows Forms control still looks like a Windows Forms control and does not have all the resizing and styling features you get with WPF.

image from book
Figure 31-47




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net