• Home >> Visual C / C++ >>  Button Controls
  • a templated pleasewait button, introduction to template control


  • Rating : Excellent[0]   Very Good[0]   Average[0]   Below Average[0]   Poor[0]
  • Pub Date: 10/30/2008
  • admin [ View Profile ]

  • Abstract
  • 1.This article presents the construction of a templated ASP.NET control, working as a PleaseWait button. Using C# with Asp.Net 2.0, you will see how to create a templated control and add specific fonctionnality.Some times, you need to perform some long task during a click button event, when submiting your page. Some times, the form's validation can request some call to database, or remoted call, web services ... To inform the user that ......

  • Introduction
  •  Sponsored Links
  • 1.introduction

    this article presents the construction of a templated asp.net control, working as a pleasewait button. using c# with asp.net 2.0, you will see how to create a templated control and add specific fonctionnality.

    some times, you need to perform some long task during a click button event, when submiting your page. some times, the form's validation can request some call to database, or remoted call, web services ... to inform the user that the server is doing something long, it's a good idea to display a waiting message.

    i've seen some articles that re-create a button with an added properties, that display a message. but the presentation never suits to me. so i decided to create a complete one, customizable with a template fonctionnality.

    2.the result to optain

    what i want to have, is something like this in my asp.net page :

    <test:pleasewaitbutton id="pwb" runat="server">
        <pleasewaitmessagetemplate>
            <div style="width:500px;color:green;border:1px solid red;text-align:center">
                <div>please wait a moment, </div>
                <div>we are checking your informations ...</div>
                <asp:image runat="server" imageurl="wait.gif" />
            </div>
        </pleasewaitmessagetemplate>
    </test:pleasewaitbutton>

    then we have the button, and the place to define the graphic visualisation of the please wait message.

    to look like a real button, we need to define a event hanndler on the button click. we want to be able to customize the text of the button, with the text property too.

    in a form, usually we want to use ap.net validation. then the button need to check this validation and define if needed a validationgroup property.

    <test:pleasewaitbutton id="pwb" runat="server" onclick="clickbutton" validationgroup="mygroup" text="please click">
        <pleasewaitmessagetemplate>
            <div style="width:500px;color:green;border:1px solid red;text-align:center">
                <div>please wait a moment, </div>
                <div>we are checking your informations ...</div>
                <asp:image runat="server" imageurl="wait.gif" />
            </div>
        </pleasewaitmessagetemplate>
    </test:pleasewaitbutton>

    3.creating the template button

    first, you have to inherits from control and implement inamingcontainer. you have to define the parsechildren(true) attribute too.

    [system.security.permissions.permissionset(system.security.permissions.securityaction.demand, name = "fulltrust")]
    [parsechildren(true)]
    [defaultproperty("text")]
    public class pleasewaitbutton : control, inamingcontainer
    {
    }

    4.1.the itemplate property

    this is all you need : having a template propety. persistencemode is used to tell the parser that property persist as inner property. templatecontainer is unused here, it's for databind typing.

    private itemplate _pleasewaitmessagetemplate = null;
    
    [browsable(false), defaultvalue(null), persistencemode(persistencemode.innerproperty), 
        templatecontainer(typeof(templateitem))]
    public itemplate pleasewaitmessagetemplate
    {
        get { return _pleasewaitmessagetemplate; }
        set { _pleasewaitmessagetemplate = value; }
    }

    we need to define a templateitemp class too.

    // templateitem should implement inamingcontainer
    [toolboxitem(false)]
    public class templateitem : control, inamingcontainer
    {
    }
    

    4.2.creation of the controls

    we'll override the createchildcontrols method to create a panel that will contains our control. in this panel, if the user defines a template, we instanciate it (as a templateitem). if no template is defined, we create a default literalcontrol with a default message.

    and just after, we add a button, with a click handler defined and with text property set to our text property.

    with css style, we set the panel to display none. the button, outside the panel, is always visible.

    protected override void createchildcontrols()
    {
        controls.clear();
        // create an hidden panel
        panel panelmessage = new panel();
        panelmessage.attributes["style"] = "display:none";
        if (pleasewaitmessagetemplate != null)
        {
            // if a template is defined, use it
            templateitem templateitem = new templateitem();
            pleasewaitmessagetemplate.instantiatein(templateitem);
            panelmessage.controls.add(templateitem);
        }
        else
        {
            // else, create a default ugly message
            panelmessage.controls.add(new literalcontrol("plesae wait ..."));
        }
    
        // button is created with text property
        // and a click handler
        button boutonvalidation = new button();
        boutonvalidation.text = text;
        boutonvalidation.click += b_click;
    
        // then add panel and button
        controls.add(panelmessage);
        controls.add(boutonvalidation);
    }
    

    4.3.creation of the properties

    as seen, we need to hold a validationgroup property and a text property.

    if no text is defined, we use the default "ok" value.

    we define a click event too.

    to ensure control creation, let's override the controls property and call ensurechildcontrols() (that will call createchildcontrols if needed)

    [bindable(true), category("behavior"), description("validation group")]
    public string validationgroup
    {
        get { return (string)viewstate["validationgroup"] ?? string.empty; }
        set { viewstate["validationgroup"] = value; }
    }
    
    [bindable(true), category("appearance"), defaultvalue("ok"), description("button's text")]
    public string text
    {
        get { return (string)viewstate["text"] ?? "ok"; }
        set { viewstate["text"] = value; }
    }
    
    private event eventhandler _clickhandler;
    public event eventhandler click
    {
        add { _clickhandler += value; }
        remove { _clickhandler -= value; }
    }
    
    public override controlcollection controls
    {
        get { ensurechildcontrols(); return base.controls; }
    }
    

    4.4.validation

    we have to ask for the validation of the page (with page.validate method). if a validationgroup is defined, we ask for validation of this group.

    private void b_click(object sender, eventargs e)
    {
        // manual validation
        if (!string.isnullorempty(validationgroup))
            page.validate(validationgroup);
        else
            page.validate();
        // fire the user-define click event, if defined
        if (_clickhandler != null)
            _clickhandler(sender, e);
    }
    

    4.4.client-side javascript

    on the client-side, we have to do 2 things :

    - client validation

    - and display/hide the please wait message

    this is done with javascript, we will play with the display style of the panel (represented as a div html), if validation is ok or nok.

    so let's add some javascript in the rendering phase, to call a specific javascript function on the clientclick button event (see comments).

    but first, we have to find the clientid of the panel.

    protected override void onprerender(eventargs e)
    {
        // we look for the panel and set an id
        // warning : this operation can't be done in createchildcontrols, it would have been too earl
        panel panelmessage = null;
        foreach (control control in controls)
        {
            if (control is panel)
            {
                control.id = id + "_waiting";
                panelmessage = (panel) control;
            }
        }
        // when panel founded, look for the button, and add a clientside function 
        //(with panel clientid as parameters)
        if (panelmessage != null)
        {
            foreach (control control in controls)
            {
                if (control is button)
                {
                    ((button) control).onclientclick = 
                        string.format("checkform('{0}')", panelmessage.clientid);
                }
            }
        }
        base.onprerender(e);
    }

    on render, create the javascript functions that will manage the display, depending on the result of the client validation (client validation is done with page_clientvalidate method)

    protected override void render(htmltextwriter writer)
    {
        // script client-side creation :
        // if there's a validation group, call validation function with the group as parameters
        // else without parameters
        string validationgroupparameters = string.isnullorempty(validationgroup) ? 
                string.empty : string.format("'{0}'", validationgroup);
    
        // if validation is ok, display panel (and waiting message)
        // if validation nok, hide panel and return false
        string script = @"function getobj(id)
    {
        var o;
        if (document.getelementbyid)
        {
            o = document.getelementbyid(id).style;
        }
        else if (document.layers)
        {
            o = document.layers[id];
        }
        else if (document.all)
        {
            o = document.all[id].style;
        }
        return o;
    }
    function setdisplay(id)
    {
        var o = getobj(id);
        if (o)
        {
            o.display = 'block';
        }
    }
    function unsetdisplay(id)
    {
        var o = getobj(id);
        if (o)
        {
            o.display = 'none';
        }
    }
    function checkform(divwaiting)
    {
        try
        {
            if (!page_clientvalidate(" + validationgroupparameters + @"))
            {
                unsetdisplay(divwaiting);
                return false;
            }
        }
        catch (e) {}
        setdisplay(divwaiting);
    }";
        page.clientscript.registerstartupscript(gettype(), "javascriptbutton", script, true);
    
        base.render(writer);
    }

    4.create a default page that use this button :

    4.1.with no validation

    just define the template control, and the template property. add if needed a click button handler

    <test:pleasewaitbutton id="pwb" runat="server" onclick="clickbutton">
        <pleasewaitmessagetemplate>
            <div style="width:500px;color:green;border:1px solid red;text-align:center">
                <div>please wait a moment, </div>
                <div>we are checking your informations ...</div>
                <asp:image runat="server" imageurl="wait.gif" />
            </div>
        </pleasewaitmessagetemplate>
    </test:pleasewaitbutton>
    

    in code behind, simulate the long task to perform ...

    protected void clickbutton(object sender, eventargs e)
    {
        thread.sleep(2000);
    }
    

    4.2.with validation

    4.2.1.without validation group

    let's define a textbox and add a client side validation with a requiredfieldvalidator control and a server side validation with a customvalidator control.

    <asp:textbox runat="server" id="atextbox" />
    <asp:requiredfieldvalidator runat="server" controltovalidate="atextbox" 
        errormessage="field should have a value" display="dynamic"/>
    <asp:customvalidator runat="server" onservervalidate="validatefunction" 
        display="dynamic" errormessage="value should be abc" />
    
    protected void clickbutton(object sender, eventargs e)
    {
        if (page.isvalid)
        {
            thread.sleep(2000);
            response.write("<br/>informations are ok<br/>");
        }
    }
    
    protected void validatefunction(object source, servervalidateeventargs args)
    {
        args.isvalid = atextbox.text == "abc";
    }
    
    

    4.2.2.with validation group

    you can try with a validation group too, like this :

    <asp:textbox runat="server" id="atextbox" />
    <asp:requiredfieldvalidator runat="server" controltovalidate="atextbox"
        errormessage="field should have a value" display="dynamic" validationgroup="mygroup"/>
    <asp:customvalidator runat="server" onservervalidate="validatefunction" 
        display="dynamic" errormessage="value should be abc" validationgroup="mygroup"/>
    
    <test:pleasewaitbutton id="pwb" runat="server" onclick="clickbutton" validationgroup="mygroup">
        <pleasewaitmessagetemplate>
            <div style="width:500px;color:green;border:1px solid red;text-align:center">
                <div>please wait a moment, </div>
                <div>we are checking your informations ...</div>
                <asp:image runat="server" imageurl="wait.gif" />
            </div>
        </pleasewaitmessagetemplate>
    </test:pleasewaitbutton>
    
    
    protected void clickbutton(object sender, eventargs e)
    {
        if (page.isvalid)
        {
            thread.sleep(2000);
            response.write("<br/>informations are ok<br/>");
        }
    }
    
    protected void validatefunction(object source, servervalidateeventargs args)
    {
        args.isvalid = atextbox.text == "abc";
    }
    
    

    5.preview

    6.conclusion

    i hope you'll find this template button usefull and have maybe learn how to create a template control in asp.net with c#.

    validation is a critical point and very usefull method in asp.net page. knowing how to take advantage of validation with the validation api can be very powerfull too.

    if you see an error in this article, in the source code or for any other information, let me a comment.

  • RATE THIS ARTICLE :
  •  
    • Latest Comments:
      • Add a comment
      • Title:
      • Comment
      •  
    Other popular Button Controls articles:
    • cool push menu button

      This article shows the use of a Push button with a drop down menu, similar to the one found in the Office 2000 suite. The code is encapsulated in a MFC class. The class itself is derived from a CButton class, by deriving from this class most of the button behavior is supplied. The main core of the c

    • an easy way to create transparent button

      I wanted to draw a button which is transparent to its back ground image and hence had gone through several articles about button styles - transparent buttons. They were all very tedious tasks of making a button transparent - erase button back ground, draw picture etc. I found an easy method. The ide

    • a shiny orb button in gdi+

      I was actually experimenting with different brush options to create a glassy orb, but it did not work .. But, I still liked the effect even though it wasn't really what I wanted .. So, I turned this into a button. Hopefully, someone may find this useful. When the world is going to WPF ... Using the

    • J# Browser Controls

      This short hands on article will show you how to convert Java Applets written for the Sun JDK 1.1.4 into J# Browser Controls. A J# Browser Control is the equivalent to the Java Applets in the .NET world. Before any clients can view any J# Browser Controls, they must first install these redists in th

    • wowbuttons with the gdidrawstream function

      ThemeButton is a CButton derived class. It is a very simple graphical button, and has special bitmaps representing five button states: normal, hot, pressed, disabled, and default. Buttons are drawn as Windows draws it's theme-changeable buttons. Each theme bitmap has a background color and it's tran

    • unicode owner draw button control

      When I was writing an application for an Arabic customer in C++, I noticed that the buttons/labels in my CDialog did not understand my Arabic text. This class allows you to write any Unicode text in the button control. (And you can use it as a direction for making the same for a static label, for in

    • transparent button with region and anti-aliased edges

      This is an example of how to create and use masked and semi-transparent bitmap buttons that can be overlaid on any background, including other bitmaps. The buttons are automatically alpha-blended (anti-aliased) with the background to create nice smooth edges, and provide region clipping to create va

    • transparant image button (bmp, gif, jpg...)

      *I'm not good at English, but if you can understand my story, isn't that enough? :)When I made this application, especially as dialog based, a lot of buttons were used. Buttons are very important things in my situation. So I decided to make an Image button source.As you know, there are many sources

    • cbutton with icon

      The idea was to have a small piece of code which makes it easy to create a button with an icon on it. I saw a lot of great code, but it was not exactly what I want. So I decided to create my own CIconButton-class. This class makes it easy to set an icon on a button.Simply add a button to your dialog

    • sbbutton

      SBButton control is a button control from a set of controls (Sysbytes Controls) I'm developing to use with an application I'm writing. This button control can be customized in almost anyway the user prefers. You can have different styles for different states of this control, e.g.: DefaultStyle, Mous

    About Us |Contact us |Site Map |Csharp |Visual C / C++ |Visual basic |Java |SQL |Linux / Unix |Ajax
    ©2007-2018 CodeCoolest.com. Ptolive.cn Asp.net source code All Rights Reserved.