Codegod - The page for .NET-developers
Winforms Grid TreeList Control .NET 2.0/3.5

Integration of WinForms in WPF-Applications
Section: WPFRating: Not rated yet!

Add to YiGGAdd to google-bookmarksAdd to linkarenaAdd to redditAdd to del.icio.usAdd to misterwongAdd to digg


zip-attachment Attachment




Introduction

WPF is a new technology for implementing rich graphical user interfaces with .NET. It has a powerful engine based on DirectX which offers a lot of new possibilities to design your GUI. But what's about existing WinForms-applications? Is there a way to convert these to WPF? In this article is explained how to integrate WinForms into WPF-applications.


Figure 1

The concept


Developing WPF-applications is fun but migrating existing WinForms-projects to WPF means a lot of work and effort. Think of a control-library based on WinForms with many special controls. Wouldn't it be nice to reuse them in a WPF-application. For that use-case, Microsoft offers a control to host WinForms-controls: The WindowsFormsHost. You can place this control with the designer of VS 2008 Beta 2 to your WPF-Window and host your existing WinForms-controls in it. How this can be done is described by an example in this article.

The example


In the sample-project we display a list of Person-objects in a DataGridView-control. This DataGridView is added to a UserControl that is hosted in a WindowsFormsHost-control. When the user selects a Person-object in the DataGridView and clicks the Button "Show details", some detail-info and a picture of the person is displayed below the DataGridView. The Image, the Button and the Labels with the detailed-info of a person are WPF-controls.

1. The WinForms UserControl
For the interaction of the DataGridView and the WPP-Window we have to methods in the UserControl hat holds the DataGridView:

public void SetData(List<Person> persons) { gridViewPersons.DataSource = persons; } public Person GetSelectedPerson() { if (gridViewPersons.SelectedRows.Count == 0) return null; }

The first method gets a list with Person-objects and displays it in the DataGridView by binding the List to the DataGridView. The second method returns the selected Person in the Grid, so that we can display the detailed info in the WPF-part of the application.

This is how the GUI of the UserControl looks like:


Figure 2

2. The Person-class
This class just holds the data for a person and has as static method for creating an instance:

public class Person { public static Person Create(string name, string street, string city, DateTime birthDay, string imageRef) { Person person = new Person(); person.Name = name; person.Street = street; person.City = city; person.BirthDay = birthDay; person.ImageRef = imageRef; return person; } private string _name; public string Name { get { return _name; } set { _name = value; } } private string _street; public string Street { get { return _street; } set { _street = value; } } private string _city; public string City { get { return _city; } set { _city = value; } } private DateTime _birthDay; public DateTime BirthDay { get { return _birthDay; } set { _birthDay = value; } } private string _imageRef; public string ImageRef { get { return _imageRef; } set { _imageRef = value; } } }

3. The WPF-Window
The main Window named WpfWindow is created with the designer of VS 2008 Beta 2. Because we created a WPF application the template for this window already has been created. We enhanced it with two Grid-rows, a Button, two Labels for the detailed info about a person, an Image-control for the person's picture and in the first row of the Grid there is the WindowsFormsHost-control:


Figure 3

This is how the Xaml looks like:

<Window x:Class="WpfAppTest.WpfWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WinForms in WPF integration" Height="322" Width="398.142" xmlns:my="clr-namespace:System.Windows.Forms.Integration; assembly=WindowsFormsIntegration"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="221.796*" /> <RowDefinition Height="62.204" /> </Grid.RowDefinitions> <Button Grid.Row="1" Margin="0,6.363,8,9" Name="btnDisplayDetails" Click="btnDisplayPersons_Click" OverridesDefaultStyle="False" HorizontalAlignment="Right" Width="105.209"> <Button.BitmapEffect> <DropShadowBitmapEffect /> </Button.BitmapEffect>Show details</Button> <WindowsFormsHost Grid.Row="0" Margin="6,9,8,8" Name="winFormHost" /> <Image Grid.Row="1" HorizontalAlignment="Left" Margin="6,6.363,0,9" Name="imgPerson" Width="57.267"> <Image.BitmapEffect> <DropShadowBitmapEffect /> </Image.BitmapEffect> </Image> <Label Grid.Row="1" Margin="69.993,4,126.351,0" Name="lblName" ClipToBounds="False" SnapsToDevicePixels="False" FontSize="10" Height="24.9349999999999" VerticalAlignment="Top"></Label> <Label Margin="69.993,27,126.351,11" Name="lblAge" Grid.Row="1" ClipToBounds="True" FontSize="10" /> </Grid> </Window>

4. Integrating WinForms
Okay, now we are integrating our WinForms-UserControl to the WindowsFormsHost-control. We just have to create it and assign it to the Child-property of the WindowsFormsHost in the constructor of the WpfWindow. After that we create some sample-Person-objects and assign them to the UserControl by using our interface

public WpfWindow() { InitializeComponent(); // Create WinForms Usercontrol and // add it to the WindowsFormsHost _ucPersons = new UCPersons(); winFormHost.Child = _ucPersons; List<Person> persons = CreateSamplePersons(); _ucPersons.SetData(persons); }

5. WinForms and WPF-interaction
We need to get the detail-info of the selected Person-object in the DataGridView to display it in the WPF-controls. This is done in the Click-eventhandler of the WPF-Button

private void btnDisplayDetails_Click(object sender, RoutedEventArgs e) { Person person = _ucPersons.GetSelectedPerson(); if (person != null) { lblName.Content = person.Name; lblAge.Content = person.BirthDay.ToShortDateString(); Uri uri = new Uri( "m_" + person.ImageRef + ".jpg", UriKind.Relative); imgPerson.Source = BitmapFrame.Create(uri); } }

That's all, the sampple-project is attached. In the next WPF-article the reverse case will be described: Integrating WPF in a WinForms-GUI. Have fun!




 Reader-Comments: