Ajax Control Toolkit

Creating a new extender

The following steps walk you through the process of creating a new ASP.NET AJAX extender from scratch. When you've completed this walkthrough, you'll have written a completely new extender control that you can customize and use in your own ASP.NET web pages.


Prerequisites
  1. If you haven't already done so, follow the steps to setup your environment
Creating the foundation
  1. Using Visual Studio 2005, create a new web site from the ASP.NET AJAX web site template by opening the "File" menu, clicking "New", "Web Site...", and picking "ASP.NET AJAX Web Site" under "My Templates"
  2. Open the "File" menu, click "Add", and "New Project..." from the menu
  3. Chose C# or VB and then select the "ASP.NET AJAX Control Project" item from the "My Templates" section.
  4. Name the new project DisableButton
  5. This will create you the default template project. Four files are automatically created:
    • DisableButtonBehavior.js - This file is where you will add all of your client script logic.
    • DisableButtonExtender.cs - This file is the server-side control class that will manage creating your extender and allow you to set the properties at design-time. It also defines the properties that can be set on your extender. These properties are accessible via code and at design time and match properties defined in the DisableButtonBehavior.js file.
    • DisableButtonDesigner.cs - This class enables design-time functionality. You should not need to modify it.
Ensuring the Client Behavior is Setup Properly
  1. Open DisableButtonBehavior.js by double-clicking it
  2. Add the test code alert("Hello World!"); immediately below the line this._myPropertyValue = null;
  3. Open Default.aspx by double-clicking it in the Solution Explorer
  4. Switch to design view by clicking the Design tab
  5. Add a TextBox (TextBox1) by dragging one over from the Toolbox
  6. Add a Button (Button1) by dragging one over from the Toolbox
  7. Build your solution by opening the "Build" menu and choosing "Build Solution" from the menu
  8. At the top of the Toolbox, you'll find a tab called "DisableButton Components". Inside will be an item called "DisableButtonExtender". Drag this onto your page.

    Note: If you do not find the item in the Toolbox, you can add it manually with the following steps:

    1. Switch to Source view
    2. Add a reference to the assembly by right clicking the website, choosing "Add Reference...", "Projects", and "DisableButton"
    3. Register the reference in your web page by adding the following code at the top of the page: <%@ Register Assembly="DisableButton" Namespace="DisableButton" TagPrefix="cc1"%> Note: If you are using Visual Basic, the namespace will be "DisableButton.DisableButton"
    4. Add the control to the page: <cc1:DisableButtonExtender ID="DisableButtonExtender1" runat="server"/>
    5. You can now switch back to Design view
  9. Hook up the extender by clicking on the DisableButtonExtender, going to the Properties panel, expanding the TargetControlID property, choosing "TextBox1"
  10. Run the page by pressing F5 (enable debugging if prompted) and verify that the page brings up a "Hello World!" dialog when it loads
  11. Close the browser window
Adding functionality
  1. Remove the test code alert("Hello World!"); added to DisableButtonBehavior.js earlier
  2. Limit the extender to TextBoxes by changing "Control" to "TextBox" in the TargetControlType attribute in DisableButtonExtender.cs: [TargetControlType(typeof(TextBox))]
  3. Create a better property name by renaming as follows (case is important):
    1. "MyProperty" to "TargetButtonID" in DisableButtonExtender.cs (3 locations)
    2. "MyProperty"/"myProperty" to "TargetButtonID" in DisableButtonBehavior.js (5 locations)
  4. Add a new DisabledText property by following the example of the TargetButtonID property just modified (case is important):
    1. Add a new public string property to DisableButtonExtender.cs:
      [ExtenderControlProperty]
          public string DisabledText { 
              get {
                  return GetPropertyValue("DisabledText", ""); 
              }
              set { 
                  SetPropertyValue("DisabledText", value);
              }
          }
    2. Add a new member variable to the behavior in DisableButtonBehavior.js below the existing member variable for TargetButtonIDValue: this._DisabledTextValue = null;
    3. Add property get/set methods to the behavior in DisableButtonBehavior.js *above* the existing get/set methods for TargetButtonID:
      get_DisabledText : function() {
              return this._DisabledTextValue;
          },
          set_DisabledText : function(value) {
              this._DisabledTextValue = value;
          },
  5. Because TargetButtonID should always refer to a control, add the attribute [IDReferenceProperty(typeof(Button))] to the property in DisableButtonExtender.cs so the framework will know to automatically resolve the control ID at render time
  6. Add a keyup handler to the behavior by adding the following code *above* the existing property definitions in DisableButtonBehavior.js:
    _onkeyup : function() {
            var e = $get(this._TargetButtonIDValue);
            if (e) {
                var disabled = ("" == this.get_element().value);
                e.disabled = disabled;
                if (this._DisabledTextValue) {
                    if (disabled) {
                        this._oldValue = e.value;
                        e.value = this._DisabledTextValue;
                    } else {
                        if (this._oldValue) {
                            e.value = this._oldValue;
                        }
                    }
                }
            }
        },
        
  7. Hook up the keyup handler by adding the following code to end of the behavior's initialize function:
    $addHandler(this.get_element(), 'keyup',
            Function.createDelegate(this, this._onkeyup));
        this._onkeyup();

    (Note: This walkthrough doesn't handle clean up in order to keep things easy understand - refer to any of the samples, and refer to the "dispose" method in the script files for examples of how to properly clean up your controls)

  8. Switch back to Default.aspx by double-clicking it in the Solution Explorer
  9. Switch to source view by clicking the Source tab
  10. Remove the old property setting by removing the following code from the DisableButtonExtender: MyProperty="property"
  11. Rebuild the solution
  12. Switch to design view by clicking the Design tab
  13. Modify the extender's properties by clicking the TextBox, going to the Properties panel, expanding the DisableButtonExtender item, and specifying "Button1" for TargetButtonID and "Enter text" for DisabledText
  14. Run the page by pressing F5, enter text into the TextBox, and note the behavior of the Button control - notice that it is disabled and says "Enter text" whenever the TextBox is empty

Congratulations, you've written your first ASP.NET AJAX extender!!


Please refer to the individual sample pages (at the left) for examples of other behaviors, and how to use them, and to the AjaxControlToolkit project for their source.