Hosting Controls in Internet Explorer


One way to deploy WinForms code over the Web is to use Internet Explorer (IE) 5.01+ to host a WinForms control on a Web page. You do this using an HTML object tag formatted appropriately:

 <object   id="iectrl"  classid="iectrl.dll#iectrl.UserControl1"  width="100"   height="100"> </object> 

The object tag is very much like the object tag used to pull in a COM control, something we've had for several versions of IE. The ID defines the variable name to be used in script code. The width and height define the dimensions that the control will draw itself into.

Control Creation

The only thing that's different is the classid attribute. Instead of specifying a COM class ID (CLSID), classid specifies the name of the .NET type to create in the form:

 <dll>#<namespace>.<class> 

The sample classid attribute shown in Figure 15.1 refers to the UserControl1 class in the iectrl namespace in the iectrl.dll assembly. This classid will cause IE to download the DLL (if it's not already cached), create an instance of the iectrl.UserControl1 class, and show it on the Web page.

Figure 15.1. A WinForms Control Hosted in IE

The control in Figure 15.1 is a UserControl that looks like Figure 15.2 in the Designer.

Figure 15.2. The Sample Control Shown in the Designer

As part of the creation process, you can augment the object tag with nested param tags that set public properties on the control after a successful creation:

 <object id="iectrl" ...>  <param name="somethingPrefix" value="hi! " />  </object> 

This code sets the SomethingPrefix property of the newly created UserControl1 object to the value "hi! ". Setting of parameters is pretty loose in that the case doesn't matter, nor do the double quotes around the value (unless you're embedding spaces, as in this example). All reasonable means will be used to find the appropriate property and to convert the value to the appropriate type. If there is no public property named SomethingPrefix, the parameter will be ignored.

Control Interaction

After you've created the object, you can set properties and call methods in client-side script using the same syntax you'd use for the native objects of the scripting language itself:

 <!-- page.htm --> ... <input   type="button"   value="Say Something"  onclick="iectrl.saySomething('something')"  /> 

This HTML creates a button that, when pressed, calls the SaySomething method of the iectrl object, which just happens to be the WinForms control created earlier in the object tag. Similar HTML can be used to handle the control's events:

 <!-- page.htm --> ...  <script for="iectrl" event="OuchEvent(degree)">  alert("Ouch to the " + degree + "th degree!");  </script>  

This HTML creates an event handler for the iectrl object that handles the OuchEvent, taking a single argument. Until now, all the interoperability mappings between unmanaged COM objects on the IE side and managed objects on the .NET side have been seamless as far as the control was concerned . To be hosted in IE, a WinForms control merely has to derive ultimately from the Control class, implement a public constructor that takes no arguments, and expose public properties and methods. [1] However, exposing events requires greater work. For example, the UserControl1 class exposes a single public event:

[1] Technically, to be hosted in IE, a WinForms control must also set the assembly-side AllowPartiallyTrustedCallersAttribute, which is discussed in more detail later in this chapter.

 // UserControl1.cs ... namespace iectrl {  public delegate void OuchCallback(int degree);  public class UserControl1 : UserControl {  public event OuchCallback OuchEvent;  ...   } } 

To expose a control's events to IE requires bundling them into a COM source interface, which is a list of methods that constitute events that a COM object will fire. To bundle a set of .NET events into a COM source interface, you must list the events as methods whose names match the names of the events in the .NET control and whose signatures match the delegates of which the methods are instances:

 // UserControl1.cs ...  [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface IOuchEvents {   [DispId(1)]  void OuchEvent(int degree);  } 

In addition to listing each event as a method, you must use the DispID attribute to mark each method in the interface with an interface-unique, positive integer needed by COM. Also, you must use the InterfaceType attribute to mark the interface as a whole as a COM source interface. Both attributes come from the System.Runtime.InteropServices namespace.

After defining the interface, you also must use the ComSourceInterfaces attribute (also from the System.Runtime.InteropServices namespace) to mark the control that fires the events from that interface:

 // UserControl1.cs ...  [ComSourceInterfaces(typeof(IOuchEvents))]  public class UserControl1 : UserControl {...} 

This combination of attributes will provide the COM wrapper around your .NET control with enough metadata to perform the mapping needed to expose events to HTML in IE. Unfortunately, exposing events to IE isn't enough to actually fire events. You must do two more things before this will work.

The first additional requirement is that you increase permissions so that code deployed from the Web has permission to make the transition from managed to unmanaged code. This can be accomplished by awarding Full Trust to the assembly that contains the control. For this, you use the Trust An Assembly Wizard available from Start Settings Control Panel Administrative Tools Microsoft .NET Framework Wizards. This process is discussed at length later in this chapter.

The second requirement for firing events into unmanaged code is that you grant the permission to call unmanaged code to the managed code hosting your WinForms controls. You use the Assert method of the permission object:

 // UserControl1.cs ... void label1_Click(object sender, EventArgs e) {  // Assumes assembly granted unmanaged code permissions   SecurityPermissionFlag flag = SecurityPermissionFlag.UnmanagedCode;   SecurityPermission perm = new SecurityPermission(flag);   perm.Assert();// DANGER! (read on!)  if( OuchEvent != null ) OuchEvent(10); } 

However, it's very likely that neither of these requirements makes sense unless you're familiar with .NET's security model, which I discuss next .



Windows Forms Programming in C#
Windows Forms Programming in C#
ISBN: 0321116208
EAN: 2147483647
Year: 2003
Pages: 136
Authors: Chris Sells

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