http://aspnet.4guysfromrolla.com/articles/052604-1.aspx
Hosting a Windows Control in a Web Form
By Tim Stall
Introduction
ASP.NET is an incredibly powerful and extensible technology, especially with its ability to create User Controls and Custom Controls. While User Controls and Custom Controls are designed to be displayed in a browser, there may be real-world scenarios where you want to display a Windows Control in a Web browser. While there are some caveats involved with hosting Windows Controls in an ASP.NET Web page, there are also a number of benefits, as hosting Windows Controls can:
- Offer more functionality than just ASP.NET. For example complex treeviews, circular drawing, and user interaction are easier to build in Windows forms than ASP.NET.
- Offer better performance because complex functionality doesn't require postbacks. The client downloads the control once, and then can interact with it without reposting to the server.
- Save time because the control may already be built, and be sufficiently complicated that there's not time to rebuild it on a busy project.
- Act as an intermediate step to migrate a Windows application to or from ASP.NET
In this article we'll examine the steps you'll need to take to start hosting a Windows Control in an ASP.NET Web page.
First Things First: Creating the Windows Control
This article demonstrates how to host a single Windows Control in three different types of projects:
- A Windows Control Library that contains the control itself,
- A Windows Application to test that control, and
- An ASP.NET Web Application, showing how to host a Windows Control in a Web page.
All of these projects are available for download at the end of this article. To get started, first create a blank solution named HostWinControlInAspx
. Create this in your C:/inetpub/wwwroot
because it will make it cleaner when you integrate it with the ASP.NET project later. Now add to the solution a Windows Control Library (NOT a Class Library). Name this new project WinControls
. For starters we'll create just a single User Control named WinTreeview.cs
. Drag a GroupBox onto the control, and then drag a Treeview into the GroupBox. Use the GroupBox's text property for a title, and encapsulate this like so (in C#):
public string Title { get { return this.groupBox1.Text; } set { this. groupBox1.Text = value; } } |
When finished, the Windows User Control should look something like the image shown below.
![Screenshot of Windows Control.](http://aspnet.4guysfromrolla.com/images/WinControl.jpg)
Let's test this control by adding a Windows Application project (named WinTestControls
) to the solution. Note that it is much easier to test and debug a Windows User Control in a Windows App than in an ASP.NET App. From the ToolBox's "My User Controls" section, drag your User Control onto the default Form1. Look in the User Control's Properties window, and set Title
to My Title
. Set the Windows App as the startup project and run it to confirm that the User Control works correctly.
Lastly, let's create the ASP.NET Web application that actually hosts the Windows Control. Add a new ASP.NET Web application project to the solution and name it WebGUI
. In IIS, the application needs to be configured for "Execute Permissions" to be "Scripts Only", which Visual Studio does by default.
![Screenshot of IIS settings.](http://aspnet.4guysfromrolla.com/images/IIS_Properties.jpg)
Copy the physical DLL (as opposed to adding a Reference) from the Windows Control library into the root folder for the Web app. Simply adding a reference will not allow you to reference the Windows Control. Likewise if you update your Windows Control, rebuilding the solution won't get the changes for the ASP.NET project – you need to recopy the DLL instead.
Although you could host the control in an HTML file, let's create a WebForm named SetStatic.aspx
, and add the following HTML in the body:
<OBJECT id="MyWinControl1" height="200" width="200" classid="http:WinControls.dll#WinControls.WinTreeview" VIEWASTEXT> |
If you have added Java applets of ActiveX controls to a Web page before, you'll note that adding a Windows Control to an ASP.NET Web page uses the same HTML markup - an <OBJECT>
element. In the markup above, the <OBJECT>
element's id
, height
, and width
attributes are assigned values. The ClassId
is divided into two parts separated by a #
: the location of the binary DLL on the server and the namespace of the control. Control Parameters can be set with the <PARAM name="[PropertyName]" value="[PropertyValue]">
notation.
Build the ASP.NET Web application and visit the ASP.NET Web page through a browser; you should see something like the screenshot below:
![Screenshot of a Windows Control in an ASP.NET Web page.](http://aspnet.4guysfromrolla.com/images/ASPX_SetStatic.jpg)
Dynamically Adding Windows Controls
Although this is sufficient to demonstrate hosting a Windows Control, let's take it one step further. What if you needed to dynamically create controls, or change the properties at runtime? You can do this by adding raw HTML to a Literal Web control. To demonstrate this, create a second WebForm named SetDynamic.aspx
. Add a TextBox Web control named TxtTitle
to hold the Title
property, along with a Button, and a Literal control. Add the following code to the Button's Click
event:
string strTitle = this.TxtTitle.Text; |
The Title
PARAM
's value is dynamically set based on the value from the Title
TextBox. You can use this technique to create instances of the Windows Control at run time, as well as set its properties. Using this dynamic approach, you're page should look something like:
![Screenshot of a Windows Control in an ASP.NET Web page.](http://aspnet.4guysfromrolla.com/images/ASPX_SetDynamic.jpg)
Limitations
Hosting a Windows Control in ASP.NET has several limitations worth discussing. First it requires both that the client machines have, at minimum, the .NET redistributable installed and be browsing with Internet Explorer 5.01 or later. While this may work for a corporate intranet, it is not feasible for a public Internet application. Second, while ASP.NET can host both Windows User Controls and Custom Controls, it cannot host Windows Forms. Therefore if you want to host parts of your Windows app in ASP.NET, you'll need to abstract those parts to Windows Controls. Lastly, because the Windows Control is not a Web control that can be run at the server, the properties can not be easily set or read during a postback. We saw earlier that you can effectively set the properties dynamically via the PARAM
elements, but getting data from a Windows Control is much more difficult.
There are two categories of solutions for reading and writing data from a hosted Windows Control. Perhaps the easiest is to have the Windows Control do the processing such that there is no need for the host ASP.NET page to read data from it. For example the Windows Control's methods could handle all database transactions by making a connection back to the Web server's database. If encapsulating functionality to the Windows Control is not feasible, you could always have it write to an external XML file: first the user triggers an event on the Windows Control to push data to an XML file, and then they trigger an event on the host ASP.NET page to pull that data back to the Web server to parse it. However, it is significantly slower to pass data via writing to and reading from external files. There is not a clean way to pass data to and from Windows Controls, and this is a notable limitation.
Conclusion
Hosting Windows Control in an ASP.NET Web application offers considerable business value. You can host a Windows Control by first creating the control, copying the DLL into an ASP.NET app, and adding the control with the <OBJECT>
tag. Visual Studio, by default, creates ASP.NET applications with the configuration needed for this. You can dynamically generate Windows Controls by adding the raw HTML to an ASPX page.
Happy Programming!
- By Tim Stall