Custom Controls

From Visual WebGui Wiki

Jump to: navigation, search


Contents

Custom Controls

Future Contents

This article should discuss Custom Controls in general, how and why you create them, how you create them, how you configure for them etc..

For the new 6.4 features, references should be made to the new Theme and Controls designer, as appropriate.

General

Custom control options/paths

Windows Forms way

Developers coming from the Windows Forms world, often get a bit frustrated when they start thinking of custom controls capabilities in Visual WebGui. Those developers are used to the fact that in Windows Forms UI programming, you can intercept quite many of the drawing routines that handle drawing (rendering) of the control, and that way customize the control drawing in details.

Visual WebGui way

In Visual WebGui the server-side code (the .cs or .vb) and the client resources (the .xslt, .js, .css, .html) are seperated, the server-side code running only on the server and the client resources/code running only on the client. Transfering screen updates in Visual WebGui is not handled by sending bitmap information from the server to the client, rather a delta of required updates/changes is constructed/built and and sent to the client as an Xml. It is very important to understand that this Xml contains information about what data needs to be updated on the client, not exactly how it should be done. It is the client browser's and client core code's responsibility to interpret these deltas of changes and update them on the form within the browser.

Visual WebGui controls are custom controls

To put custom control creation into a little more common perspective, then all of the Visual WebGui controls in the standard Out-Of-The-Box SDK toolbox are custom controls. Some are built from scratch, some inheriting from another control, and adding some capabilities.

Options for creating custom controls

There are quite a few options one can choose from when deciding how to create/construct a new or enhanced control. The more common ones are:

  1. For the most simple type of controls, that don't really need any interaction with your Visual WebGui application, you can either statically or dynamically build the Html code for the control and then show it within an HtmlBox inside of your application.
  2. Build your control from scratch (grounds up). In that case you will need to supply both the server-side code (the .cs or .vb), as well as the client resources (.xslt, .js, .css ...). For samples of this implementation, you can pick just about any control in the open source standard Visual WebGui toolset and take a look at it's implementation.
  3. Inheriting from another existing control. In this case you would then enhance the server-side code only, the client-side code only, or both. As a sample of such implementation, you can view any of the standard controls that inherit from another standard control, say the LinkLabel.
  4. Use and ASP.NET control and wrap it using the Integrated ASP.NET wrapper in Visual WebGui. As an example on this, you can view any of the walkthroughs on wrapping in the KB.
  5. Use an Html or JavaScript based controls and wrap them "manually". Some examples of this can be found within the SDK (FCKEditor) and also the CKEditor sample, as well as the Aurigma upload control.
  6. As the last option listed here, then for some cases you can use server-side controls to dynamically create an image that you will then render to the client through a gateway. As an example of this type of "wrapping", you can view our Gauges sample and also the Gantt sample.

Design-Time customization

Visual WebGui designer uses the idea of Controllers to bridge betweeen the Visual WebGui control it is designing and the Windows Forms control used for visualization within the deisnger UI. For this purpose, every controller type keeps an instance of the Visual WebGui control and a Windows Forms control, and bridges between them during design time operations.

For customization you need to create a custom controller class, inheriting from any of the standard (or base) Visual WebGui controllers available within Gizmox.WebGUI.Forms.Design (actually, most of the controllers within this assembly are inheriting from controllers defined within the Gizmox.WebGUI.Client assembly, where you will find most of the code).

After you have created a custom design-time controller for your control, you need to activate it on your custom control using the DesignTimeController attribute on your class.

In addition to view the public source for Gizmox.WebGUI.Client and Gizmox.WebGUI.Forms.Design, see the System.ComponentModel namespace, that has valuable information on many of the features used for design-time customization, like information on attributes you can place on your properties and classes. The RefreshProperty attribute deserves special mention here, as it will help you to adjust how properties will get updated within the propertygrid of the designer, if their value is updated from the change of another property..

UserControl property to update Text on an internal Label

In this example you create a new UserControl and place a Label control on it. Then you create a public property on the UserControl that on Get will retrieve the Label.Text and on Set with set Label.Text. This works well at runtime, but introduces problems at Design time, namely that when you add an instance of your UserControl to a form and set the new property's text, the changes are not reflected in the designer, meaning the label within the UserControl does not change the text. Only by closing down the form and reopening it in the designer, you will see the internal label updated.

This is a good example of how the design time controller (keeping one instance of a Windows Forms control and another instance of a Visual WebGui control) is unable to "know" that by setting a property on your UserControl it should update a Text property on an internal label. In order to make this work property, you have to "help" the design time controller accomplishing this task.

For this purpose, you create a custom design time controller class, inheriting from UserControlController. Then you override OnSourceObjectPropertyChange (source object is the Visual WebGui control instance) and when your new property changes (in this case the "DisplayText" property) you make sure the update will also be reflected on the internal Windows Forms Control's Label.Text property.

The download below is a Visual Studio 2010 Visual WebGui project so it can not be opened directly in Visual Studio 2005 or 2008. The code that matters for this demo's purposes can be found inside the UserControl1 and Form1 files, so for VS2005 and VS2008 you can create a new project and then add those files as existing items into that project.

Design-Time customization references

Forum threads
Other references

Case studies

Tips and Tricks

When to use @Attr.Property and when to use @Property

When customizing controls with XSLT and JavaScript, a very common mistake is to try "overusing" the @Attr prefix for the custom attributes added to your custom control.

To clear up the confusion here are some facts for properties in XSLT and JavaScript in Visual WebGui:

  • @Attr is a prewired prefix for a set of standard Visual WebGui attributes defined by WGAttributes class in the Visual WebGui XML Protocol.
  • Visual WebGui standard attributes defined by WGAttributes class are addressed in XSLT transformations with the "@Attr." prefix - example: @Attr.Mask
  • Custom attributes rendered by your customized control are addressed in XSLT transformation as "@" followed by your rendered attribute name - example: @Mode
  • Retrieving the attributes using JavaScript, the attribute's name is without the "@" sign - example Attr.Mask , Mode

Trigger a JavaScript to run on control rendering

When creating a custom control, it can at times be necessary to trigger some JavaScript to load as a part of the rendering process, at the time the Control's Html structure has been fully built.

It may seem logical to override the Render method of the server-side control and at the end of that overridden method, call some of the InvokeScript JavaScript methods (InvokeMethod, InvokeMethodWithId, InvokeScript). In some cases, this is not the right place to invoke that JavaScript, as slowly loading (heavy) controls could have the JavaScript invoked before the Html structure has been fully initialized.

In such cases, you can add a dummy img tag to your .XSLT that will invoke the JavaScript onload, which will then occur after the Html structure has been initialized and is ready.

As an example of such a dummy img tag within an XSLT file, you may use:

<img style="visibility:hidden;height:0;width:0" 
      src="Resources.Gizmox.WebGUI.Forms.Skins.CommonSkin.Empty.gif.wgx" 
      onload="mobjApp.YourControl_YourJavaScriptMethod('{@Id}');" >
</img>

This will add an invisible image, showing an empty image, but will call your JavaScript method with one parameter, the Id or Guid of the control. The call will take place when the img is ready (loaded).

See also

References

Forum Threads

Task Tracker entries

Videos

Articles

Other References


Personal tools