Home  |  FAQ  |  About  |  Contact  |  View Source   
 
SEARCH:
 
BROWSE:
    My Hood
Edit My Info
View Events
Read Tutorials
Training Modules
View Presentations
Download Tools
Scan News
Get Jobs
Message Forums
School Forums
Member Directory
   
CONTRIBUTE:
    Sign me up!
Post an Event
Submit Tutorials
Upload Tools
Link News
Post Jobs
   
   
Home >  Tutorials >  C# >  User Controls for Windows and the Web
Add to MyHood
   User Controls for Windows and the Web   [ printer friendly ]
Stats
  Rating: 4.62 out of 5 by 13 users
  Submitted: 04/03/02
Heath Stewart ()

 
If you have an application that targets both Windows and the Web, chances are you've had to design dual interfaces for each platform. Even if your only target is the Web, you may have requirements that cannot be completely or efficiently fulfilled by an ASP.NET Web Form. You may, instead, use an embedded User Control both in your Windows Forms and your Web Forms.

This tutorial will cover basic design strategies for coding your controls for use with both Windows and the Web. Topics include basic control design, events, COM dispatch events, and security concerns to ensure that your controls work on either platform. Additional topics not covered in depth include setting toolbox icons for your control and setting category and description attributes for your public and protected properties and events to make your control as robust as the controls in the .NET Framework.


Helpful Tutorials

In order to keep this tutorial shorter, I would like to point out a few tutorials previous written about some topics covered briefly here.
  1. Embedded Windows User Controls into Internet Explorer - Basic concepts of control design for use as an embedded User Control in Internet Explorer (Andrew Ma).
  2. Introduction to C# Events - Basic concepts of adding events to your control (Kevin Chan).


Introduction

Embedding user controls in a Windows form or Web Form is just like adding a simple button or text box that are already provided with .NET. These basic controls were written essentially like you code your own controls. As you have probably noticed, however, such controls exist in both System.Windows.Forms and System.Web.UI.HtmlControls / System.Web.UI.WebControls. You can, instead, write one control that is capable of being hosted in both. Using your control in a Windows form is trivial, but embedding your control in a Web page (that runs client-side like an ActiveX control or Java Applet) takes a bit more designing and programming. Because of the .NET Framework, you also have to add a reference of that control to be embedded in Internet Explorer (IE) to the trusted assembly cache, which will be covered briefly torward the end of this tutorial.


Designing your Control

Typically the controls you design are to be used in multiple forms or to modularize your code. These reasons help reduce the amount of code you have to type as well as make it easier for you to change your implementation. There should almost never be any reason to duplicate code because it leaves a lot of room for bugs. So, implementing functionality specific to your control in the control's source code is a good idea. This reduces code redundency as well as modularize your code, which is a good programming guideline.

The control we will create will contain a text box for your name and a button that will fire an event. To begin, open Visual Studio .NET (VS.NET) and begin a new C# Windows Control Library. You may name it whatever you like, but for this tutorial I will keep the default project and file names. In this instance, the project name will be "WindowsControlLibrary1".

Before you add any controls to the designer, change any references to color for the user control to a standard color (in the Color enumeration). As Andrew Ma's tutorial points out (and is conveniently not documented in the framework docs), if a user control uses system colors (in the SystemColor enumeration), the control will not work (hence, not display) in IE! If you set these two properties first before you add basic controls, the BackColor and ForeColor of those basic controls will default to those colors. For more advanced controls like the DataGrid, you'll have to change the other colors as well. For our control, we'll change the BackColor to Color.White (White in the property box) and the ForeColor to Color.Black (Black in the property box).

Now drag a label control, a text control, and a button control from under the "Windows Forms" tab in the toolbox to your control and position them in a practical manner (ex, the label in the top left corner, followed by the text box with the button underneath). Change the control text for each control as follows:
  1. label1.Text = "Name:";
  2. textBox1.Text = "";
  3. button1.Text = "Submit";
Of course, do this in designer. I just use the syntax above for simplicity. If you want to add a custom bitmap image for your control that will show up in the Toolbox, add a 16x16 pixel bitmap to your project named "UserControl1.bmp" (or any name you like), mark it as an "Embedded Resource" in the property grid with the bitmap file selected, and add the following attribute to your class declaration:
[ToolboxBitmap("WindowsControlLibrary1.UserControl1.bmp")]

The string you specify is the fully-qualified name for the bitmap as is embedded in your assembly. The code up till this point should look something like the following:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace WindowsControlLibrary1
{
 /// <summary>
 /// Summary description for UserControl1.
 /// </summary>
 [ToolboxBitmap("WindowsControlLibrary1.UserControl1.bmp")]
 public class UserControl1 : System.Windows.Forms.UserControl
 {
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.TextBox textBox1;
  private System.Windows.Forms.Button button1;
  /// <summary>
  /// Required designer variable.
  /// </summary>
  private System.ComponentModel.Container components = null;

  public UserControl1()
  {
   // This call is required by the Windows.Forms Form Designer.
   InitializeComponent();

   // TODO: Add any initialization after the InitForm call

  }

  /// <summary>
  /// Clean up any resources being used.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if( components != null )
     components.Dispose();
   }
   base.Dispose( disposing );
  }

  #region Component Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify 
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {
   this.label1 = new System.Windows.Forms.Label();
   this.textBox1 = new System.Windows.Forms.TextBox();
   this.button1 = new System.Windows.Forms.Button();
   this.SuspendLayout();
   // 
   // label1
   // 
   this.label1.Location = new System.Drawing.Point(8, 8);
   this.label1.Name = "label1";
   this.label1.Size = new System.Drawing.Size(40, 16);
   this.label1.TabIndex = 0;
   this.label1.Text = "Name:";
   // 
   // textBox1
   // 
   this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Top
    | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right);
   this.textBox1.Location = new System.Drawing.Point(48, 8);
   this.textBox1.Name = "textBox1";
   this.textBox1.TabIndex = 1;
   this.textBox1.Text = "";
   // 
   // button1
   // 
   this.button1.Location = new System.Drawing.Point(48, 32);
   this.button1.Name = "button1";
   this.button1.TabIndex = 2;
   this.button1.Text = "Submit";
   // 
   // UserControl1
   // 
   this.BackColor = System.Drawing.Color.White;
   this.Controls.AddRange(new System.Windows.Forms.Control[] {
    this.button1,
    this.textBox1,
    this.label1});
   this.ForeColor = System.Drawing.Color.Black;
   this.Name = "UserControl1";
   this.Size = new System.Drawing.Size(160, 64);
   this.ResumeLayout(false);

  }
  #endregion
 }
}

Now we will add an event for the submit buttons click event. Because the .NET controls are contained within our control, events are not fired for the contained controls. Our control is treated like any other and must implement it's own properties (besides those inherited from System.Windows.Forms.Control) and events.

Where most action events (like the Click event) use the EventHandler delegate and the EventArgs arguments, we will define our own delegate that does not specify parameters. Mostly, we really don't care what the conditions of the click event for the Submit button were, we just care that the Submit button was clicked. This also makes adding a client-side event handler in IE easier. We will define a simple delegate like so:
public delegate void SubmitClickedHandler();

For simplicity, define this delegate directly under the scope of the namespace. In other words, don't define the delegate as part of a class. This leads to numerous complications.

Now inside the UserControl1 class (or whatever you called yours), we'll define the actual event. Somewhere in the scope for the UserControl1 class, add the following:
[Category("Action")]
[Description("Fired when the Submit button is clicked.")]
public event SubmitClickedHandler SubmitClicked;

protected virtual void OnSubmitClicked()
{
 if (SubmitClicked != null)
  SubmitClicked();
}

You'll notice above that we used the CategoryAttribute and DescriptionAttribute ("Attribute" may be ignored since this is implied). These define the category that this event falls under in the property grid when you have the UserControl1 control selected. The description is the description that will appear when you have the event selected in the property grid.

We also added a protected method called OnSubmitClicked(). You may use this in child classes instead of adding event handlers. If you do this, however, make sure that somewhere in your virtual method you call:
base.OnSubmitClicked();

If you do not call this, the other event listeners for the control will not be notified of the event. This also makes firing the event easy from within our code.

Finally during this design phase, we must tell our control to fire the event with the Submit button is clicked. We'll also do some simple validation of our text box content before firing the control to show you the importance of ordering your code to provide better modularity. Typically, you'll fire the event after you perform some functionality on your control, but this is not always the case.

To add an event handler for the Submit button's Click event, you may either use the designer (click on the lightning-looking button in the property grid for events and then double-click the event to add a handler with the default naming convention similar to VB's) or code it manually in your constructor like so:
public UserControl1()
{
 // This call is required by the Windows.Forms Form Designer.
 InitializeComponent();

 // TODO: Add any initialization after the InitForm call
 button1.Click += new EventHandler(this.button1_Click);
}

The event handler should then look something like this:
private void button1_Click(object sender, EventArgs e)
{
 if (textBox1.Text.Length == 0)
  MessageBox.Show("Please enter your name.");
 else
  OnSubmitClicked();
}

See how we just called OnSubmitClicked()? Using this method is the recommended way if you've read the .NET Framework SDK documents, and it also allows for more modular code.

Before we finish, we will define a property named "UserName" (because "Name" is already defined by the control base) with get and set accessors in order to get the text in the text box from a client application that contains this control:
[Category("Appearance")]
[Description("Gets or sets the name in the text box")]
public string UserName
{
 get { return textBox1.Text; }
 set { textBox1.Text = value; }
}

Without defining this property, there would be no way to get the text in the control since contained controls aren't exposed without manually coding it. Your code should now look like the following:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace WindowsControlLibrary1
{
 public delegate void SubmitClickedHandler();

 /// <summary>
 /// Summary description for UserControl1.
 /// </summary>
 [ToolboxBitmap("WindowsControlLibrary1.UserControl1.bmp")]
 public class UserControl1 : System.Windows.Forms.UserControl
 {
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.TextBox textBox1;
  private System.Windows.Forms.Button button1;
  /// <summary>
  /// Required designer variable.
  /// </summary>
  private System.ComponentModel.Container components = null;

  public UserControl1()
  {
   // This call is required by the Windows.Forms Form Designer.
   InitializeComponent();

   // TODO: Add any initialization after the InitForm call

  }

  /// <summary>
  /// Clean up any resources being used.
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if( components != null )
     components.Dispose();
   }
   base.Dispose( disposing );
  }

  #region Component Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify 
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {
   this.label1 = new System.Windows.Forms.Label();
   this.textBox1 = new System.Windows.Forms.TextBox();
   this.button1 = new System.Windows.Forms.Button();
   this.SuspendLayout();
   // 
   // label1
   // 
   this.label1.Location = new System.Drawing.Point(8, 8);
   this.label1.Name = "label1";
   this.label1.Size = new System.Drawing.Size(40, 16);
   this.label1.TabIndex = 0;
   this.label1.Text = "Name:";
   // 
   // textBox1
   // 
   this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Top 
    | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right);
   this.textBox1.Location = new System.Drawing.Point(48, 8);
   this.textBox1.Name = "textBox1";
   this.textBox1.TabIndex = 1;
   this.textBox1.Text = "";
   // 
   // button1
   // 
   this.button1.Location = new System.Drawing.Point(48, 32);
   this.button1.Name = "button1";
   this.button1.TabIndex = 2;
   this.button1.Text = "Submit";
   this.button1.Click += new System.EventHandler(this.button1_Click);
   // 
   // UserControl1
   // 
   this.BackColor = System.Drawing.Color.White;
   this.Controls.AddRange(new System.Windows.Forms.Control[] {
    this.button1,
    this.textBox1,
    this.label1});
   this.ForeColor = System.Drawing.Color.Black;
   this.Name = "UserControl1";
   this.Size = new System.Drawing.Size(160, 64);
   this.ResumeLayout(false);

  }
  #endregion

  [Category("Action")]
  [Description("Fires when the Submit button is clicked.")]
  public event SubmitClickedHandler SubmitClicked;

  protected virtual void OnSubmitClicked()
  {
   if (SubmitClicked != null)
    SubmitClicked();
  }

  private void button1_Click(object sender, System.EventArgs e)
  {
   if (textBox1.Text.Length == 0)
    MessageBox.Show("Please enter your name.");
   else
    OnSubmitClicked();
  }
  [Category("Appearance")]
  [Description("Gets or sets the name in the text box")]
  public string UserName
  {
   get { return textBox1.Text; }
   set { textBox1.Text = value; }
  }
 }
}

Please not this will be the last time the sample code is given for brevity. Now lets add support for scripting to our control.


Adding Support for Scripting Events

Before we actually start using our control in either Windows or the Web, we want to make the control available for scripting as an embedded user control. To do this, we must travel back to COM and briefly discuss dispatch events.

Every COM object implements an interface. The base interface for all COM objects, of course, is IUnknown. COM objects also have their own interface they implement that defines properties and methods. Client applications that use COM know about these properties and methods but not about the implementation. The class that implements the interface takes care of the implementation but how does the client know which class implements the interface? While there are a number of ways and I won't attempt to explain them all (hey, this isn't a COM tutorial!), the interface knows the CLSID of the class that implements it. The CLSID is a 128-bit unique identified known as a GUID, or globally unique identifier. .NET makes this easy through attributes defined in the System.Runtime.InteropServices namespace.

To add support for scripting events to our control so that we can listen for events in a web page (or a COM client, for that matter), we must define an interface like a developer would in COM.

Add the following directly under the scope of the namespace (i.e., not in the class declaration for UserControl1):
[ComVisible(true)]
[Guid("61CD00DB-E9BC-484d-9033-83D41112EBD4")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface UserControl1Events
{
 [DispId(0)]
 void SubmitClicked();
}

The "GuidAttribute" takes a string that is a unique GUID. To generate your own GUID, use the guidgen.exe utility installed with VS.NET (available from the Tools menu by default). Note for all you COM developers out there that this string does not include the "{" and "}" braces. We also mark the interface as an IDispatch interface, basically meaning that this interface is used for displatch events as I briefly mentioned above. The method (or event) is also marked with an attribute that is necessary for scripting. This is a unique ID (Dispatch ID) that is used to lookup the method in the VTABLE (not discussed in this tutorial) for the COM interface. If you define more than one Dispatch event, increment the number for each method but keep the number the same for get and put accessors of properties.

Now add the following attributes to the namespace itself like so:
[assembly: ClassInterface(ClassInterfaceType.AutoDual)]
[assembly: SecurityPermission(
    SecurityAction.RequestMinimum,
    UnmanagedCode=true)]

To be able to use these attributes, you must also import the System.Security.Permissions and System.Runtime.InteropServices namespaces. So, toward the top of your source file with the rest of the imports, add:
using System.Runtime.InteropServices;
using System.Security.Permissions;

The first attribute is necessary for the IDispatch interface to work with the class. The second attribute is necessary in order for the control to work with unmanaged code, such as JavaScript, which we'll use in a bit. Permissions will be discussed in more detail in a future tutorial.

To specify that our UserControl1 class implements the IDispatch interface we defined above, we do not necessarily implement it like you would a standard interface. You can, but it isn't necessary. To do this, add the following attributes to your UserControl1 class definition:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(UserControl1Events))]

This tells the COM interop services that our class's source interface for which events are defined is the UserControl1Events interface we defined above.

Finally, compile your control and lets add it to a Windows form and a Web Form.


Using your Control in a Windows Form

Using the control in a Windows form is trivial. It's just like adding any other control like a button or a DataGrid. First, add a new Windows Application project to your solution (use the existing solution for a nifty little helper thanks to VS.NET).

So, right-click on your solution and select Add->New Project... Select "Windows Application" and click "OK". A new "WindowsApplication1" project should now exist in our solution. Go ahead and right-click on it and select "Set as StartUp Project" to have this application start when we start the debugger (since we can't execute a library anyway).

With the Form1 form open in the designer, look in your toolbox and you'll see that VS.NET has already added our UserControl1 control to the toolbox! If you make any changes to your control from this point on, you must close both the control and form in the designer and open them back up to reflect changes made in the control. Go ahead and drag UserControl1 onto the Windows form. VS.NET will also automatically add a reference to your project's assembly in the WindowsApplication1 references.

You'll notice the control is white since we had to change all the SystemColor references to just plan Color references. You can change this. Select the control and find the BackColor property in the property grid. Change this to SytstemColor.Control ("Control" in the designer). Also change the ForeColor to SystemColor.ControlText ("ControlText" in the designer). Now you have a normal-looking control.

Now we want to handle the SubmitClicked event for the user control. This will simply close the form. The control itself will take care of validation and the event won't be fired unless the text is valid. Click on the lightning-looking button (for events) with the control selected and you'll see our event, "SubmitClicked", listed under the "Action" category. Click on it once and you'll see our description we added previously. Now double-click it and VS.NET will add an event handler called "userControl11_SubmitClicked()". Add the following code to display the name from the user control and close the form when the event is fired:
private void userControl11_SubmitClicked()
{
 MessageBox.Show(String.Format("Hello, {0}!", userControl11.UserName));
 this.Close();
}

Since this form is the application instance form, simply closing it will quite the application.

That's it! Go ahead and run the application and try it out. Next we will add the user control as an embedded control in IE.


Using your Control in a Web Form

Embedding your control in Internet Explorer is a bit more tricky. First, the assembly containing the control must be added to the trusted assembly cache in one form or another. Also, because .NET does not apparently have a mechanism for a control to implement IObjectWithSafety (which marks a control as being safe for scripting which was previously done with ActiveX controls), the client's browser must allow for such controls to be scripted. Not even adding a Microsoft Authenticode signature to the control will help in this case, but does help in another.

If you are writing a web-based application that uses many client-side user controls that are implemented in two or more assemblies (DLLs), it would get tedious to add all these control URLs to the trusted assembly cache. If you SSL sign each one, you can add one assembly to the trusted assembly cache (which I'll cover in a moment) and tell .NET to trust all assemblies from this publisher, which is information obtained from the SSL object-signing certificate.

Since Microsoft apparently neglected to declare an interface or define an attribute for IObjectWithSafety, the security settings of your browser must be changed. To do this, open your "Internet Properties", select the "Security" tab, and change the Internet zone's properties by clicking "Custom Level..." and set "Initialize and script ActiveX controls not marked as safe" to "Enabled". If you're testing this on your own machine using "localhost" as the host name, also do this for the "Local intranet" zone, too.

If you do not SSL-sign the assemblies, you must also set "Download unsigned ActiveX control" to "Enabled" or "Prompt" in the same manner as above. You may also find it convenient to set "Download signed ActiveX controls" to "Enabled" instead of "Prompt", but this is entirely up to you.

Before we add the assembly to the trusted assembly cache, we must first upload it to our web server. To do this, add a new ASP.NET Web Application to our solution like we did for the Windows Application above. Right-click on WebForm1.aspx and select "Set as Start Page". You can also set this as the StartUp project if you like in the same manner as we did with the Windows Application project.

Now comes the manual part of our operation. Because the assembly containing our User Control must be accessible to the client's browser, we must right-click on the WebApplication1 project and select "Add->Add Existing Item...". Browse to the output directory for the WindowsControlLibrary1 project and add "WindowsControlLibrary1.dll". DO NOT add this to the "bin" subdirectory of your Web Application, however. This directory is not accessible by default for security reasons. This is the directory where VS.NET and ASP.NET store your compiled assemblies. The assembly containing UserControl1 must be accessible. Simply adding this project as a reference will not work, either, because it places the assembly in the "bin" subdirectory. We must add the file manually. Don't forget to re-add this file if you make changes to your control library!

To insert the control on your page, view the source for the WebForm1.aspx file (not the source code, but the HTML), and add the following:

<object id="userControl11"
classid="WindowsControlLibrary1.dll#WindowsControlLibrary1.UserControl1">
 <param name="ForeColor" value="Blue">
</object>

If you've read Andrew Ma's tutorial (listed at the top), you already know what's going on here. If you haven't (shame on you), this is the same tag used for ActiveX controls but instead of a CLSID (class identifier), we put the URL to the DLL (can be absolute or relative), followed by a pound sign ("#"), followed by the fully-qualified type (or class name) of the control. This includes the namespace the control is in and the control's class name itself. If you want, you can also add parameters that assign values to the control's base properties. Since our control implements the "ForeColor" property (from the base class's properties), you can specify that and it's value. You can also assign a default value to our text box by setting a value to the "UserName" property similar to "ForeColor" above. Feel free to also customize the width, height, and other attributes or styles you wish.

To handle the SubmitClicked event in our web page, you can either use the old-style event handler syntax (like assigning a function to window.load), or the semi-new style, which I'll use here. Add the following code somewhere in your HTML (I recommend between the <head> tags):

<script for="userControl11" event="SubmitClicked" language="javascript">
 alert("Hello");
</script>

That will cause a similar effect to our Windows Application. Now we must tell .NET to trust this assembly or else it won't be initialized.

To add the assembly to the trusted assembly cache, you can either use the caspol.exe utility installed with the .NET Framework (which works good for when you want to have a installation that simply calls caspol.exe and adds the assembly to the cache), or use the Microsoft .NET Framework Wizards in your Administration Tools folder (in the Control Panel).

Start the Microsoft .NET Framework Wizards utility and select "Trust an Assembly". Select the appropriate action ("Make changes to this computer" or "Make changes for the current user only"), select "Next", then type the full URL and click "Next". For simplicity, change the trust level to "Full Trust", then click "Next" followed by "Finish". After you've finished that process, click on "Adjust .NET Security" in the Wizard and change the "Local Intranet" zone to "Full-trust". There are other, more secure ways of doing this, but as I stated before, it will possibly discussed in a future tutorial as there is much to discuss.

As you can see, this is a pain-staking process. That's why I recommend you make a simple installation package or script that will use caspol.exe to add the assembly in this manner. I leave that for you to explore.

Go ahead and start the Web Application. You should see your control in the web page after a moment. Enter some text and press the Submit button. Neat, huh?


Summary

This tutorial just scratches the surface of what you can do with embedded User Controls. I hope you found it as a good starting reference, however. There is also a lot of security concerns and the methods I spoke of here are no recommended, although they don't completely put your system in a comprimising situation. Also, since .NET does not apparently provide a mechanism to implement IObjectWithSafety, the embedded control will not work unless IE's security for a particular zone allows ActiveX controls to be initialized and scripted even if they're not marked as safe (i.e., implements IObjectWithSafety). If you know of a way around this (I searched for weeks), I would appreciate an email!

So, consider taking the time to use a single control in both your Windows and Web applications next time you're developing. Because of the security permissions (which I'll talk more about eventually) and the application domain IE creates for the control, this tutorial and the content is describes is best suited for applications that have a targetted audience (who you can control to some extent) instead of the general public (who you really can't control...though the government tries ;-). Hopefully .NET will include additional mechanisms for embedded controls in the future, but until then, play around which the content described here and quite writing all that duplicate code!

Return to Browsing Tutorials

Email this Tutorial to a Friend

Rate this Content:  
low quality  1 2 3 4 5  high quality

Reader's Comments Post a Comment
 
Great job, in depth!
-- Sean Fitzgerald, April 04, 2002
 
Great job Heath.. if only this tutorial was a month or so earlier. I had to do my own controls and I needed help. Good ol MSDN and a lot of looking up finally solved it all, but your tutorial is great.
-- Victor Vuong, April 05, 2002
 
A good tutorial.
-- Brian Simoneau, April 05, 2002
 
While you said it may have only scratched the surface, it had quite a bit of depth for a tutorial. Excellent work. Thanks for spending your time doing it.
-- Matt Toner, April 05, 2002
 
Nice tutorial to get people started on making forms. It might be nicer if you had highlighted the code in which you changed, when you showed all the code together.
-- Brett Waldman, April 05, 2002
 
Thank you, it was really good for me.. I was reading it to get an idea and an introduction to subject.
-- Bertan Aygun, April 05, 2002
 
Well done, Great job!
-- Sean Fitzgerald, April 07, 2002
 
Brett, sorry about that. I did have that change in my local text file but apparently forgot to update the text in the textarea for this site. If you're interested, I'll send you the full source. Let me know (that goes for everyone else, too, just use the email system for DevHood instead of personal email...enough to go through already!).
-- Heath Stewart, April 08, 2002
 
Cool tutorial, nice work
-- can comertoglu, April 09, 2002
 
Nice depth, Heath. *****
-- BYU FAN, April 09, 2002
 
For those interested in the completed source, please download the ZIP file from http://www.devhood.com/Tools/tool_details.aspx?tool_id=526.
-- Heath Stewart, April 12, 2002
 
I just wanted to mention that if you change the ClassInterfaceTypeAttribute to ClassInterfaceType.AutoDispatch on the UserControl1 class, you can get access via COM (thus, scripting) to any public method or property, including UserName. This is necessary to get the UserName text field from the control via scripting in Internet Explorer.
-- Heath Stewart, April 23, 2002
 
just one small problem - if my control needs to use other, third party, assemblies, it doesn't work anymore. How can I trigger IE to download also additional dll's that are needed by the main dll (the one given in the HTML page)????
-- Dan Azmo, August 16, 2002
 
Dan (and anyone else wondering, for that matter), it's actually quite easy. .NET gives you superb control over the runtime for free. All you have to do is know how to use it. There is an ongoing thread at http://www.devhood.com/messages/message_view-2.aspx?thread_id=71605 right now where I'm explaining a lot of this stuff. About half-way down the page, I have an extensive post about setting up the runtime so that .NET can find all the dependent assemblies.

The solution I designed for our company is very abstract (both modular and data-wise) and uses many assemblies deployed from the 'net. I have a large .config file for the main executable (not a hosted control, but the runtime and security policies work the same) that contains such runtime configurations for about 20 to 30 controls (good thing we have the Temporary Assembly Cache to cache all those!). It does work well and it quite easy to do once you understand what's going on.
-- Heath Stewart, August 21, 2002
 
Hey. this is pretty cool. it's good to see what .NET can do!
-- Tony Tsang, August 26, 2002
 
Great tutorial, very informative, thanks.
-- Brent Bishop, August 26, 2002
 
Nice work, 5 star!
-- Larry Mak, August 29, 2002
 
Going into this I wasn't even sure what a control was. I'll definitely be using them more now, if not just to get even more comfortable with them. *****
-- Lee B, September 01, 2002
 
Also see the article by Jay Allen in MSDN Magazine, January 2002:
"Host Secure, Lightweight Client-Side Controls in Microsoft Internet Explorer"


-- asdfasdf sdfasdf, September 20, 2002
 
This is really great but I have a little dummy question. Will this control be displayed on any client? meening if the client does not have .Net installed on his\her PC would this control display on their IE?

-- morad ashraf, April 09, 2003
 
Does anyone have any experience serving a control like this from a non-windows non-IIS server? I like the possibilities that this technology brings, but I would like to be able to serve the files from an apache/linux platform. Since the execution is all done on the client side I don't see why it wouldn't work but I haven't had any luck so far. Has anyone else tried this with different experience?
-- Eric Harding, April 30, 2003
 
Copyright © 2001 DevHood® All Rights Reserved