Creating form controls

Creating a Simple Form Control

This document will guide you through the following steps:

  1. Creating an ASP.NET User Control that inherits from UserControlBasedUiControl.
  2. Registering the file in the Composite.config file.
  3. Editing the markup of the form that should contain your new form control and adding the markup that activates the control.

Creating the User Control file

  1. Create an ASP.NET User Control in a folder of your choice (e.g. /Controls/FormControls/MyTextBox.ascx).
  2. In the “code behind” file (e.g. MyTextBox.ascx.cs) add the required namespaces: Composite.C1Console.Forms and Composite.Plugins.Forms.WebChannel.UiControlFactories, inherit your control class from the abstract class UserControlBasedUiControl (instead of System.Web.UI.UserControl) and implement this class by adding the functions InitializeViewState and BindStateToControlProperties.
  3. Add a property with a getter and a setter for each property you want your form tag to have.
    For instance, if your form tag should be like this:
    <MyTextBox MaxLength="5" Text="Some sample text" />

    Then you should add two properties named “MaxLength” and “Text” to your control. The properties should be public and have the attribute FormsProperty specified on them.

  4. If a property should be able to communicate data back and forth, it should be marked with the BindableProperty attribute.
  5. Add the desired ASP.NET controls and markup to your User Control. In the sample code below a TextBox control with the ID of myAspNetTextBox is assumed.
  6. Add code to InitializeViewState that initialize your ASP.NET controls. This function is called by the system when a form is rendered for the first time. A typical action is to copy data from your properties to your ASP.NET controls.
  7. Add code to BindStateToControlProperties that copy user input from your ASP.NET controls to the system. This function is called by the system when a form is saved. It’s only necessary to copy data to properties with the BindableProperty attribute specified. Otherwise, the system won’t allow saving data from properties without this attribute.

MyTextBox.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyTextBox.ascx.cs" Inherits="Controls_FormControls_MyTextBox" %>
<asp:TextBox ID="myAspNetTextBox" runat="server">
</asp:TextBox>

Download the source

MyTextBox.ascx.cs

using System;
using Composite.C1Console.Forms;
using Composite.Plugins.Forms.WebChannel.UiControlFactories;
public partial class Controls_FormControls_MyTextBox : UserControlBasedUiControl
{
    [FormsProperty()]
    public int MaxLength
    {
        get;
        set;
    }
    [BindableProperty()]
    [FormsProperty()]
    public string Text
    {
        get;
        set;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    public override void BindStateToControlProperties()
    {
        this.Text = myAspNetTextBox.Text;
    }
    public override void InitializeViewState()
    {
        myAspNetTextBox.Text = this.Text;
        myAspNetTextBox.MaxLength = this.MaxLength; 
    }
}

Download the source

Validating User Input

The Form Control can also validate the user’s input before the form is saved. For example, on DateTime fields, if the value is not valid, this will prevent the form from being saved and a validation balloon will pop up on the field with the message you specify.

To add validation to the form control, use the IsValid and ValidationError properties in the BindStateToControlProperties method:

public override void BindStateToControlProperties()
{
  try
  {
    // ...
    this.IsValid = true;  
  }
  catch (Exception ex)
  {
    this.IsValid = false;
    this.ValidationError = "This is a validation error";
  }
}

Please note that this validation feature is available out-of-the-box on Composite C1 (now C1 CMS) v.3.2 or later. On Composite C1 (now C1 CMS) v 3.0 and 3.1, for the validation, the form controls should implement the Composite.C1Console.Forms.IValidatingUiControl interface.

Registering a User Control based Form UI Control

When you register your own Form UI Controls, you should first come up with, and register, an XML namespace.

Basically, this can be any unique string, but often an URI is used here.

This is important to ensure that Form UI Controls from different providers are uniquely identifiable.

Registering a Form UI Control namespace for the first time

Registering your own namespace is only necessary the first time and is done like this (“http://www.contoso.com/ns/Composite/Forms/1.0” is used here – ensure that you use your own string or URI for the namespace):

Before you proceed, ensure that the file /App_Data/Composite/Composite.modified.config does not exist.

(If the file does exist, the system has outstanding configuration changes, which must be stored before you can continue. To fix this, restart the ASP.NET application. You can do so by recycling the application pool or by making a change to the /web.config file (edit it, add an empty line, save it).)

  1. Edit the file /App_Data/Composite/Composite.config.
  2. Locate the section <Composite.C1Console.Forms.Plugins.ProducerMediatorConfiguration> and the Mediators element below. Below it, add a new element like this (remember to customize the namespace):
    <add type="Composite.C1Console.Forms.StandardProducerMediators.UiControlProducerMediator, Composite" name="http://www.contoso.com/ns/Composite/Forms/1.0" />
  3. Locate the section <Composite.C1Console.Forms.Plugins.UiControlFactoryConfiguration> and the Channel element below, with the name property of “AspNet.Management”.
  4. Under the Namespaces element, add a new Namespace element, with the name of your namespace, like:
<Namespace name="http://www.contoso.com/ns/Composite/Forms/1.0"></Namespace>

Registering the User Control based Form UI Control

To register your ASP.NET User Controls as a Form UI control, execute the following steps:

  1. Edit the file /App_Data/Composite/Composite.config.
  2. Locate the section <Composite.C1Console.Forms.Plugins.UiControlFactoryConfiguration> and the Namespace element below, named with the namespace of your organization.
  3. In the Factories element below your organization’s Namespace element, add this element:
<Namespace name="http://www.contoso.com/ns/Composite/Forms/1.0">
  <Factories>
    <add userControlVirtualPath="~/Controls/FormControls/MyTextBox.ascx" name="MyTextBox" cacheCompiledUserControlType="false" type="Composite.Plugins.Forms.WebChannel.UiControlFactories.UserControlBasedUiControlFactory, Composite" />
  </Factories>
</Namespace>

Please edit the value of the properties:

  • userControlVirtualPath: it should contain the path to your User Control file
  • name: it should contain the name the form markup tag should have

Adding a custom tag to a data form

  1. In the Data perspective, select the data type and click Edit Form Markup on the toolbar.
  2. Locate the spot where you wish to add your own User Control-based Form UI Control.
  3. To create a new control on the form, add the following markup:
    <MyTextBox MaxLength="5" Text="Some sample text" xmlns="http://www.contoso.com/ns/Composite/Forms/1.0" />
  4. Alternatively, to bind the Text property to the existing data field “MyStringField”, add the following markup:
    <MyTextBox MaxLentgh="5" xmlns="http://www.contoso.com/ns/Composite/Forms/1.0"> 
      <MyTextBox.Text> 
        <bind source="MyStringField" xmlns="http://www.composite.net/ns/management/bindingforms/1.0" /> 
      </MyTextBox.Text> 
    </MyTextBox>
  5. Save the form markup.