How to integrate Peter Blum's validation controls into the ASP.NET wizard.

by Paul Smith 16. October 2008 12:38

I came across an interesting problem recently when trying to take advantage of Peter Blum's excellent validation controls. Since the standard ASP.NET Wizard control uses standard button controls none of Peters Validation controls fire, unless you use one of his button controls or use his NativeControlExtender.

One option available is to define navigation templates for your Wizard but this can be a pain if you have several Wizards across your site. I wanted my own control that did all the validation and I wanted to add a validation group at the same time. So I created a control that inherited the standard wizard control

   1: using System;
   2: using System.Web.UI;
   3: using System.Web.UI.WebControls;
   4: using System.ComponentModel;
   5:  
   6: namespace Lib
   7: {
   8:     [ToolboxData("<{0}:CustomWizard runat=server></{0}:CustomWizard>")]
   9:     public class CustomWizard : Wizard
  10:     {
  11:     }
  12: }

First step was to add a property to hold the validation group

   1: [Description("The validation group of the next/previous buttons")]
   2: public string ValidationGroup
   3: {
   4:     get
   5:     {
   6:         object o = ViewState["ValidationGroup"];
   7:         return (o == null) ? string.Empty : (string)o;
   8:     }
   9:     set
  10:     {
  11:         ViewState["ValidationGroup"] = value;
  12:     }
  13: }

Then I need to find the buttons within the Wizard add a NativeControlExtender and assign the button to it, then set the validation group on each. Finding the buttons was a bit of pain and it's not the prettiest code (I'll tidy it up when I get the chance). Note the lines of code that make the appropriate button visible, this is important as the client side code will not render unless the control is visible.

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     Table table = (Table)this.Controls[0];
   4:     int x = 0;
   5:     
   6:     // The navigation buttons are in the last table row...
   7:     foreach (Control control in table.Rows[table.Rows.Count - 1].Cells[0].Controls)
   8:     {
   9:         // Each of the navigation containers is a table
  10:         // There'll be a prettier way of doing this.
  11:         if (control.Controls[0] is Table)
  12:         {
  13:             Table t = (Table)control.Controls[0];
  14:  
  15:             // The buttons exist in the table cells
  16:             foreach (TableCell cell in t.Rows[0].Cells)
  17:             {
  18:                 // There is a button of each type LinkButton/Button/ImageButton
  19:                 foreach (IButtonControl ctrl in cell.Controls)
  20:                 {
  21:                     // Add a validation group to the button
  22:                     ctrl.ValidationGroup = this.ValidationGroup;
  23:  
  24:                     if (ctrl is LinkButton)
  25:                     {
  26:                         // The button you want to use must be visible at this stage for the client side
  27:                         // script to get rendered. The wizard itself doesn't make them visible until the render method.
  28:                         ((Control)ctrl).Visible = true;
  29:  
  30:                         // Create a native control extender and assign the button as the control to extend
  31:                         PeterBlum.DES.NativeControlExtender nce = new PeterBlum.DES.NativeControlExtender();
  32:                         nce.ID = this.ID + "_" + (ctrl as Control).ID + x.ToString() + "_NCE";
  33:                         nce.ControlToExtend = (Control)ctrl;
  34:                         nce.Group = this.ValidationGroup;
  35:  
  36:                         // Add the NativeControlExtender to the Wizard, can't use this.Conrols.Add() as the
  37:                         // wizard does not allow it's controls collection to be modified. So I just added them 
  38:                         // in the first row as they don't render any HTML
  39:                         table.Rows[0].Cells[0].Controls.Add(nce);
  40:  
  41:                         x++;
  42:                     }
  43:                 }
  44:             }
  45:         }
  46:     }
  47: }

That handles the client side validation the final step was to add code to handle server side validation. That was a pretty straight forward affair.

   1: protected override void OnNextButtonClick(WizardNavigationEventArgs e)
   2: {
   3:     this.Page.Validate(this.ValidationGroup);
   4:     PeterBlum.DES.Globals.Page.Validate(this.ValidationGroup);
   5:  
   6:     if (!this.Page.IsValid && !PeterBlum.DES.Globals.Page.IsValid)
   7:     {
   8:         e.Cancel = true;
   9:         return;
  10:     }
  11:  
  12:     base.OnNextButtonClick(e);
  13: }
  14:  
  15: protected override void OnFinishButtonClick(WizardNavigationEventArgs e)
  16: {
  17:     this.Page.Validate(this.ValidationGroup);
  18:     PeterBlum.DES.Globals.Page.Validate(this.ValidationGroup);
  19:  
  20:     if (!Page.IsValid && !PeterBlum.DES.Globals.Page.IsValid)
  21:     {
  22:         e.Cancel = true;
  23:         return;
  24:     }
  25:  
  26:     base.OnFinishButtonClick(e);
  27: }

Putting it all together you have a custom Wizard that will handle validation groups and Peter Blum's validation control is a relatively tidy manner.

Thanks to Peter Blum for his excellent support.

Download the code for this post: CustomWizard.zip (596.00 bytes)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

ASP.NET

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen