2010-07-23 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Wizard.cs
1 //
2 // System.Web.UI.WebControls.Wizard
3 //
4 // Authors:
5 //  Lluis Sanchez Gual (lluis@novell.com)
6 //
7 // (C) 2005 Novell, Inc. (http://www.novell.com)
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_2_0
32
33 using System;
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.ComponentModel;
37 using System.Web.UI;
38
39 namespace System.Web.UI.WebControls
40 {
41         [DefaultEventAttribute ("FinishButtonClick")]
42         [BindableAttribute (false)]
43         [DesignerAttribute ("System.Web.UI.Design.WebControls.WizardDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44         [ToolboxData ("<{0}:Wizard runat=\"server\"> <WizardSteps> <asp:WizardStep title=\"Step 1\" runat=\"server\"></asp:WizardStep> <asp:WizardStep title=\"Step 2\" runat=\"server\"></asp:WizardStep> </WizardSteps> </{0}:Wizard>")]
45         public class Wizard: CompositeControl
46         {
47                 public static readonly string CancelCommandName = "Cancel";
48                 public static readonly string MoveCompleteCommandName = "MoveComplete";
49                 public static readonly string MoveNextCommandName = "MoveNext";
50                 public static readonly string MovePreviousCommandName = "MovePrevious";
51                 public static readonly string MoveToCommandName = "Move";
52 #if NET_4_0
53                 public static readonly string HeaderPlaceholderId = "headerPlaceholder";
54                 public static readonly string NavigationPlaceholderId = "navigationPlaceholder";
55                 public static readonly string SideBarPlaceholderId = "sideBarPlaceholder";
56                 public static readonly string WizardStepPlaceholderId = "wizardStepPlaceholder";
57 #endif
58                 protected static readonly string DataListID = "SideBarList";
59
60                 static readonly string CancelButtonIDShort = "Cancel";
61                 protected static readonly string CancelButtonID = CancelButtonIDShort + "Button";
62                 
63                 static readonly string CustomFinishButtonIDShort = "CustomFinish";
64                 protected static readonly string CustomFinishButtonID = CustomFinishButtonIDShort + "Button";
65                 
66                 static readonly string CustomNextButtonIDShort = "CustomNext";
67                 protected static readonly string CustomNextButtonID = CustomNextButtonIDShort + "Button";
68
69                 static readonly string CustomPreviousButtonIDShort = "CustomPrevious";
70                 protected static readonly string CustomPreviousButtonID = CustomPreviousButtonIDShort + "Button";
71
72                 static readonly string FinishButtonIDShort = "Finish";
73                 protected static readonly string FinishButtonID = FinishButtonIDShort + "Button";
74
75                 static readonly string FinishPreviousButtonIDShort = "FinishPrevious";
76                 protected static readonly string FinishPreviousButtonID = FinishPreviousButtonIDShort + "Button";
77
78                 static readonly string SideBarButtonIDShort = "SideBar";
79                 protected static readonly string SideBarButtonID = SideBarButtonIDShort + "Button";
80
81                 static readonly string StartNextButtonIDShort = "StartNext";
82                 protected static readonly string StartNextButtonID = StartNextButtonIDShort + "Button";
83
84                 static readonly string StepNextButtonIDShort = "StepNext";
85                 protected static readonly string StepNextButtonID = StepNextButtonIDShort + "Button";
86
87                 static readonly string StepPreviousButtonIDShort = "StepPrevious";
88                 protected static readonly string StepPreviousButtonID = StepPreviousButtonIDShort + "Button";
89                 
90                 WizardStepCollection steps;
91                 
92                 // View state
93                 
94                 TableItemStyle stepStyle;
95                 TableItemStyle sideBarStyle;
96                 TableItemStyle headerStyle;
97                 TableItemStyle navigationStyle;
98                 Style sideBarButtonStyle;
99                 
100                 Style cancelButtonStyle;
101                 Style finishCompleteButtonStyle;
102                 Style finishPreviousButtonStyle;
103                 Style startNextButtonStyle;
104                 Style stepNextButtonStyle;
105                 Style stepPreviousButtonStyle;
106                 Style navigationButtonStyle;
107                 
108                 ITemplate finishNavigationTemplate;
109                 ITemplate startNavigationTemplate;
110                 ITemplate stepNavigationTemplate;
111                 ITemplate headerTemplate;
112                 ITemplate sideBarTemplate;
113
114                 // Control state
115                 
116                 int activeStepIndex = -1;
117                 bool inited = false;
118                 ArrayList history;
119
120                 Table wizardTable;
121                 WizardHeaderCell _headerCell;
122                 TableCell _navigationCell;
123                 StartNavigationContainer _startNavContainer;
124                 StepNavigationContainer _stepNavContainer;
125                 FinishNavigationContainer _finishNavContainer;
126                 MultiView multiView;
127                 DataList stepDatalist;
128                 ArrayList styles = new ArrayList ();
129                 Hashtable customNavigation;
130                 
131                 static readonly object ActiveStepChangedEvent = new object();
132                 static readonly object CancelButtonClickEvent = new object();
133                 static readonly object FinishButtonClickEvent = new object();
134                 static readonly object NextButtonClickEvent = new object();
135                 static readonly object PreviousButtonClickEvent = new object();
136                 static readonly object SideBarButtonClickEvent = new object();
137                 
138                 public event EventHandler ActiveStepChanged {
139                         add { Events.AddHandler (ActiveStepChangedEvent, value); }
140                         remove { Events.RemoveHandler (ActiveStepChangedEvent, value); }
141                 }
142                 
143                 public event EventHandler CancelButtonClick {
144                         add { Events.AddHandler (CancelButtonClickEvent, value); }
145                         remove { Events.RemoveHandler (CancelButtonClickEvent, value); }
146                 }
147                 
148                 public event WizardNavigationEventHandler FinishButtonClick {
149                         add { Events.AddHandler (FinishButtonClickEvent, value); }
150                         remove { Events.RemoveHandler (FinishButtonClickEvent, value); }
151                 }
152                 
153                 public event WizardNavigationEventHandler NextButtonClick {
154                         add { Events.AddHandler (NextButtonClickEvent, value); }
155                         remove { Events.RemoveHandler (NextButtonClickEvent, value); }
156                 }
157                 
158                 public event WizardNavigationEventHandler PreviousButtonClick {
159                         add { Events.AddHandler (PreviousButtonClickEvent, value); }
160                         remove { Events.RemoveHandler (PreviousButtonClickEvent, value); }
161                 }
162                 
163                 public event WizardNavigationEventHandler SideBarButtonClick {
164                         add { Events.AddHandler (SideBarButtonClickEvent, value); }
165                         remove { Events.RemoveHandler (SideBarButtonClickEvent, value); }
166                 }
167                 
168                 protected virtual void OnActiveStepChanged (object source, EventArgs e)
169                 {
170                         if (Events != null) {
171                                 EventHandler eh = (EventHandler) Events [ActiveStepChangedEvent];
172                                 if (eh != null) eh (source, e);
173                         }
174                 }
175                 
176                 protected virtual void OnCancelButtonClick (EventArgs e)
177                 {
178                         if (Events != null) {
179                                 EventHandler eh = (EventHandler) Events [CancelButtonClickEvent];
180                                 if (eh != null) eh (this, e);
181                         }
182                 }
183                 
184                 protected virtual void OnFinishButtonClick (WizardNavigationEventArgs e)
185                 {
186                         if (Events != null) {
187                                 WizardNavigationEventHandler eh = (WizardNavigationEventHandler) Events [FinishButtonClickEvent];
188                                 if (eh != null) eh (this, e);
189                         }
190                 }
191                 
192                 protected virtual void OnNextButtonClick (WizardNavigationEventArgs e)
193                 {
194                         if (Events != null) {
195                                 WizardNavigationEventHandler eh = (WizardNavigationEventHandler) Events [NextButtonClickEvent];
196                                 if (eh != null) eh (this, e);
197                         }
198                 }
199                 
200                 protected virtual void OnPreviousButtonClick (WizardNavigationEventArgs e)
201                 {
202                         if (Events != null) {
203                                 WizardNavigationEventHandler eh = (WizardNavigationEventHandler) Events [PreviousButtonClickEvent];
204                                 if (eh != null) eh (this, e);
205                         }
206                 }
207                 
208                 protected virtual void OnSideBarButtonClick (WizardNavigationEventArgs e)
209                 {
210                         if (Events != null) {
211                                 WizardNavigationEventHandler eh = (WizardNavigationEventHandler) Events [SideBarButtonClickEvent];
212                                 if (eh != null) eh (this, e);
213                         }
214                 }
215
216             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
217             [BrowsableAttribute (false)]
218                 public WizardStepBase ActiveStep {
219                         get {
220                                 int activeIndex = ActiveStepIndex;
221                                 if (activeIndex < -1 || activeIndex >= WizardSteps.Count)
222                                         throw new InvalidOperationException ("ActiveStepIndex has an invalid value.");
223                                 if (activeIndex == -1)
224                                         return null;
225                                 return WizardSteps [activeIndex];
226                         }
227                 }
228                 
229             [DefaultValueAttribute (-1)]
230             [ThemeableAttribute (false)]
231             public virtual int ActiveStepIndex {
232                     get {
233                             return activeStepIndex;
234                     }
235                     set {
236                             if (value < -1 || (value > WizardSteps.Count && (inited || WizardSteps.Count > 0)))
237                                     throw new ArgumentOutOfRangeException ("The ActiveStepIndex must be less than WizardSteps.Count and at least -1");
238                             if (inited && !AllowNavigationToStep (value))
239                                     return;
240                             
241                             if(activeStepIndex != value) {
242                                     activeStepIndex = value;
243                                     
244                                     if (inited) {
245                                             multiView.ActiveViewIndex = value;
246                                             if (stepDatalist != null) {
247                                                     stepDatalist.SelectedIndex = value;
248                                                     stepDatalist.DataBind ();
249                                             }
250                                             OnActiveStepChanged (this, EventArgs.Empty);
251                                     }
252                             }
253                     }
254             }
255                 
256             [UrlPropertyAttribute]
257             [DefaultValueAttribute ("")]
258             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
259                 public virtual string CancelButtonImageUrl {
260                         get {
261                                 object v = ViewState ["CancelButtonImageUrl"];
262                                 return v != null ? (string)v : string.Empty;
263                         }
264                         set {
265                                 ViewState ["CancelButtonImageUrl"] = value;
266                         }
267                 }
268                 
269             [DefaultValueAttribute (null)]
270             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
271             [NotifyParentPropertyAttribute (true)]
272             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
273                 public Style CancelButtonStyle {
274                         get {
275                                 if (cancelButtonStyle == null) {
276                                         cancelButtonStyle = new Style ();
277                                         if (IsTrackingViewState)
278                                                 ((IStateManager)cancelButtonStyle).TrackViewState ();
279                                 }
280                                 return cancelButtonStyle;
281                         }
282                 }
283                 
284             [LocalizableAttribute (true)]
285                 public virtual string CancelButtonText {
286                         get {
287                                 object v = ViewState ["CancelButtonText"];
288                                 return v != null ? (string)v : "Cancel";
289                         }
290                         set {
291                                 ViewState ["CancelButtonText"] = value;
292                         }
293                 }
294                 
295             [DefaultValueAttribute (ButtonType.Button)]
296                 public virtual ButtonType CancelButtonType {
297                         get {
298                                 object v = ViewState ["CancelButtonType"];
299                                 return v != null ? (ButtonType)v : ButtonType.Button;
300                         }
301                         set {
302                                 ViewState ["CancelButtonType"] = value;
303                         }
304                 }
305                 
306             [UrlPropertyAttribute]
307                     [EditorAttribute ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
308                 [DefaultValueAttribute ("")]
309                 [Themeable (false)]
310                 public virtual string CancelDestinationPageUrl {
311                         get {
312                                 object v = ViewState ["CancelDestinationPageUrl"];
313                                 return v != null ? (string)v : string.Empty;
314                         }
315                         set {
316                                 ViewState ["CancelDestinationPageUrl"] = value;
317                         }
318                 }
319             
320             [DefaultValueAttribute (0)]
321                 public virtual int CellPadding {
322                         get {
323                                 if (ControlStyleCreated)
324                                         return ((TableStyle) ControlStyle).CellPadding;
325                                 return 0;
326                         }
327                         set {
328                                 ((TableStyle) ControlStyle).CellPadding = value;
329                         }
330                 }
331                 
332             [DefaultValueAttribute (0)]
333                 public virtual int CellSpacing {
334                         get {
335                                 if (ControlStyleCreated)
336                                         return ((TableStyle) ControlStyle).CellSpacing;
337                                 return 0;
338                         }
339                         set {
340                                 ((TableStyle) ControlStyle).CellSpacing = value;
341                         }
342                 }
343                 
344             [DefaultValueAttribute (false)]
345             [ThemeableAttribute (false)]
346                 public virtual bool DisplayCancelButton {
347                         get {
348                                 object v = ViewState ["DisplayCancelButton"];
349                                 return v != null ? (bool) v : false;
350                         }
351                         set {
352                                 ViewState ["DisplayCancelButton"] = value;
353                         }
354                 }
355                 
356             [DefaultValueAttribute (true)]
357             [ThemeableAttribute (false)]
358                 public virtual bool DisplaySideBar {
359                         get {
360                                 object v = ViewState ["DisplaySideBar"];
361                                 return v != null ? (bool) v : true;
362                         }
363                         set {
364                                 ViewState ["DisplaySideBar"] = value;
365                                 UpdateViews ();
366                         }
367                 }
368                 
369             [UrlPropertyAttribute]
370             [DefaultValueAttribute ("")]
371             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
372                 public virtual string FinishCompleteButtonImageUrl {
373                         get {
374                                 object v = ViewState ["FinishCompleteButtonImageUrl"];
375                                 return v != null ? (string)v : string.Empty;
376                         }
377                         set {
378                                 ViewState ["FinishCompleteButtonImageUrl"] = value;
379                         }
380                 }
381                 
382             [DefaultValueAttribute (null)]
383             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
384             [NotifyParentPropertyAttribute (true)]
385             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
386                 public Style FinishCompleteButtonStyle {
387                         get {
388                                 if (finishCompleteButtonStyle == null) {
389                                         finishCompleteButtonStyle = new Style ();
390                                         if (IsTrackingViewState)
391                                                 ((IStateManager)finishCompleteButtonStyle).TrackViewState ();
392                                 }
393                                 return finishCompleteButtonStyle;
394                         }
395                 }
396                 
397             [LocalizableAttribute (true)]
398                 public virtual string FinishCompleteButtonText {
399                         get {
400                                 object v = ViewState ["FinishCompleteButtonText"];
401                                 return v != null ? (string)v : "Finish";
402                         }
403                         set {
404                                 ViewState ["FinishCompleteButtonText"] = value;
405                         }
406                 }
407                 
408             [DefaultValueAttribute (ButtonType.Button)]
409                 public virtual ButtonType FinishCompleteButtonType {
410                         get {
411                                 object v = ViewState ["FinishCompleteButtonType"];
412                                 return v != null ? (ButtonType)v : ButtonType.Button;
413                         }
414                         set {
415                                 ViewState ["FinishCompleteButtonType"] = value;
416                         }
417                 }
418                 
419             [UrlPropertyAttribute]
420             [EditorAttribute ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
421             [DefaultValueAttribute ("")]
422                 [Themeable (false)]
423                 public virtual string FinishDestinationPageUrl {
424                         get {
425                                 object v = ViewState ["FinishDestinationPageUrl"];
426                                 return v != null ? (string)v : string.Empty;
427                         }
428                         set {
429                                 ViewState ["FinishDestinationPageUrl"] = value;
430                         }
431                 }
432             
433                 [DefaultValue (null)]
434                 [TemplateContainer (typeof(Wizard), BindingDirection.OneWay)]
435                 [PersistenceMode (PersistenceMode.InnerProperty)]
436             [Browsable (false)]
437                 public virtual ITemplate FinishNavigationTemplate {
438                         get { return finishNavigationTemplate; }
439                         set { finishNavigationTemplate = value; UpdateViews (); }
440                 }
441                 
442             [UrlPropertyAttribute]
443             [DefaultValueAttribute ("")]
444             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
445                 public virtual string FinishPreviousButtonImageUrl {
446                         get {
447                                 object v = ViewState ["FinishPreviousButtonImageUrl"];
448                                 return v != null ? (string)v : string.Empty;
449                         }
450                         set {
451                                 ViewState ["FinishPreviousButtonImageUrl"] = value;
452                         }
453                 }
454                 
455             [DefaultValueAttribute (null)]
456             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
457             [NotifyParentPropertyAttribute (true)]
458             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
459                 public Style FinishPreviousButtonStyle {
460                         get {
461                                 if (finishPreviousButtonStyle == null) {
462                                         finishPreviousButtonStyle = new Style ();
463                                         if (IsTrackingViewState)
464                                                 ((IStateManager)finishPreviousButtonStyle).TrackViewState ();
465                                 }
466                                 return finishPreviousButtonStyle;
467                         }
468                 }
469                 
470             [LocalizableAttribute (true)]
471                 public virtual string FinishPreviousButtonText {
472                         get {
473                                 object v = ViewState ["FinishPreviousButtonText"];
474                                 return v != null ? (string)v : "Previous";
475                         }
476                         set {
477                                 ViewState ["FinishPreviousButtonText"] = value;
478                         }
479                 }
480                 
481             [DefaultValueAttribute (ButtonType.Button)]
482                 public virtual ButtonType FinishPreviousButtonType {
483                         get {
484                                 object v = ViewState ["FinishPreviousButtonType"];
485                                 return v != null ? (ButtonType)v : ButtonType.Button;
486                         }
487                         set {
488                                 ViewState ["FinishPreviousButtonType"] = value;
489                         }
490                 }
491                 
492             [DefaultValueAttribute (null)]
493             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
494             [NotifyParentPropertyAttribute (true)]
495             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
496                 public TableItemStyle HeaderStyle {
497                         get {
498                                 if (headerStyle == null) {
499                                         headerStyle = new TableItemStyle ();
500                                         if (IsTrackingViewState)
501                                                 ((IStateManager)headerStyle).TrackViewState ();
502                                 }
503                                 return headerStyle;
504                         }
505                 }
506                 
507                 [DefaultValue (null)]
508                 [TemplateContainer (typeof(Wizard), BindingDirection.OneWay)]
509                 [PersistenceMode (PersistenceMode.InnerProperty)]
510             [Browsable (false)]
511                 public virtual ITemplate HeaderTemplate {
512                         get { return headerTemplate; }
513                         set { headerTemplate = value; UpdateViews (); }
514                 }
515                 
516             [DefaultValueAttribute ("")]
517             [LocalizableAttribute (true)]
518                 public virtual string HeaderText {
519                         get {
520                                 object v = ViewState ["HeaderText"];
521                                 return v != null ? (string)v : string.Empty;
522                         }
523                         set {
524                                 ViewState ["HeaderText"] = value;
525                         }
526                 }
527 #if NET_4_0
528             [DefaultValue (null)]
529             [TemplateContainerAttribute(typeof(Wizard))]
530                     [PersistenceModeAttribute(PersistenceMode.InnerProperty)]
531                     [BrowsableAttribute(false)]
532                     public virtual ITemplate LayoutTemplate { get; set; }
533 #endif
534             [DefaultValueAttribute (null)]
535             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
536             [NotifyParentPropertyAttribute (true)]
537             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
538                 public Style NavigationButtonStyle {
539                         get {
540                                 if (navigationButtonStyle == null) {
541                                         navigationButtonStyle = new Style ();
542                                         if (IsTrackingViewState)
543                                                 ((IStateManager)navigationButtonStyle).TrackViewState ();
544                                 }
545                                 return navigationButtonStyle;
546                         }
547                 }
548                 
549             [DefaultValueAttribute (null)]
550             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
551             [NotifyParentPropertyAttribute (true)]
552             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
553                 public TableItemStyle NavigationStyle {
554                         get {
555                                 if (navigationStyle == null) {
556                                         navigationStyle = new TableItemStyle ();
557                                         if (IsTrackingViewState)
558                                                 ((IStateManager)navigationStyle).TrackViewState ();
559                                 }
560                                 return navigationStyle;
561                         }
562                 }
563                 
564             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
565             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
566             [DefaultValueAttribute (null)]
567             [NotifyParentPropertyAttribute (true)]
568                 public TableItemStyle SideBarStyle {
569                         get {
570                                 if (sideBarStyle == null) {
571                                         sideBarStyle = new TableItemStyle ();
572                                         if (IsTrackingViewState)
573                                                 ((IStateManager)sideBarStyle).TrackViewState ();
574                                 }
575                                 return sideBarStyle;
576                         }
577                 }
578                 
579             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
580             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
581             [DefaultValueAttribute (null)]
582             [NotifyParentPropertyAttribute (true)]
583                 public Style SideBarButtonStyle {
584                         get {
585                                 if (sideBarButtonStyle == null) {
586                                         sideBarButtonStyle = new Style ();
587                                         if (IsTrackingViewState)
588                                                 ((IStateManager)sideBarButtonStyle).TrackViewState ();
589                                 }
590                                 return sideBarButtonStyle;
591                         }
592                 }
593                 
594                 [DefaultValue (null)]
595                 [TemplateContainer (typeof(Wizard), BindingDirection.OneWay)]
596                 [PersistenceMode (PersistenceMode.InnerProperty)]
597                 [Browsable (false)]
598                 public virtual ITemplate SideBarTemplate {
599                         get { return sideBarTemplate; }
600                         set { sideBarTemplate = value; UpdateViews (); }
601                 }
602
603                 [Localizable (true)]
604                 public virtual string SkipLinkText 
605                 {
606                         get
607                         {
608                                 object v = ViewState ["SkipLinkText"];
609                                 return v != null ? (string) v : "Skip Navigation Links.";
610                         }
611                         set
612                         {
613                                 ViewState ["SkipLinkText"] = value;
614                         }
615                 }
616                 
617                 [DefaultValue (null)]
618                 [TemplateContainer (typeof(Wizard), BindingDirection.OneWay)]
619                 [PersistenceMode (PersistenceMode.InnerProperty)]
620             [Browsable (false)]
621                 public virtual ITemplate StartNavigationTemplate {
622                         get { return startNavigationTemplate; }
623                         set { startNavigationTemplate = value; UpdateViews (); }
624                 }
625                 
626             [UrlPropertyAttribute]
627             [DefaultValueAttribute ("")]
628             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
629                 public virtual string StartNextButtonImageUrl {
630                         get {
631                                 object v = ViewState ["StartNextButtonImageUrl"];
632                                 return v != null ? (string)v : string.Empty;
633                         }
634                         set {
635                                 ViewState ["StartNextButtonImageUrl"] = value;
636                         }
637                 }
638                 
639             [DefaultValueAttribute (null)]
640             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
641             [NotifyParentPropertyAttribute (true)]
642             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
643                 public Style StartNextButtonStyle {
644                         get {
645                                 if (startNextButtonStyle == null) {
646                                         startNextButtonStyle = new Style ();
647                                         if (IsTrackingViewState)
648                                                 ((IStateManager)startNextButtonStyle).TrackViewState ();
649                                 }
650                                 return startNextButtonStyle;
651                         }
652                 }
653                 
654             [LocalizableAttribute (true)]
655                 public virtual string StartNextButtonText {
656                         get {
657                                 object v = ViewState ["StartNextButtonText"];
658                                 return v != null ? (string)v : "Next";
659                         }
660                         set {
661                                 ViewState ["StartNextButtonText"] = value;
662                         }
663                 }
664                 
665             [DefaultValueAttribute (ButtonType.Button)]
666                 public virtual ButtonType StartNextButtonType {
667                         get {
668                                 object v = ViewState ["StartNextButtonType"];
669                                 return v != null ? (ButtonType)v : ButtonType.Button;
670                         }
671                         set {
672                                 ViewState ["StartNextButtonType"] = value;
673                         }
674                 }
675                 
676                 [DefaultValue (null)]
677                 [TemplateContainer (typeof(Wizard), BindingDirection.OneWay)]
678                 [PersistenceMode (PersistenceMode.InnerProperty)]
679             [Browsable (false)]
680                 public virtual ITemplate StepNavigationTemplate {
681                         get { return stepNavigationTemplate; }
682                         set { stepNavigationTemplate = value; UpdateViews (); }
683                 }
684                 
685             [UrlPropertyAttribute]
686             [DefaultValueAttribute ("")]
687             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
688                 public virtual string StepNextButtonImageUrl {
689                         get {
690                                 object v = ViewState ["StepNextButtonImageUrl"];
691                                 return v != null ? (string)v : string.Empty;
692                         }
693                         set {
694                                 ViewState ["StepNextButtonImageUrl"] = value;
695                         }
696                 }
697                 
698             [DefaultValueAttribute (null)]
699             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
700             [NotifyParentPropertyAttribute (true)]
701             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
702                 public Style StepNextButtonStyle {
703                         get {
704                                 if (stepNextButtonStyle == null) {
705                                         stepNextButtonStyle = new Style ();
706                                         if (IsTrackingViewState)
707                                                 ((IStateManager)stepNextButtonStyle).TrackViewState ();
708                                 }
709                                 return stepNextButtonStyle;
710                         }
711                 }
712                 
713             [LocalizableAttribute (true)]
714                 public virtual string StepNextButtonText {
715                         get {
716                                 object v = ViewState ["StepNextButtonText"];
717                                 return v != null ? (string)v : "Next";
718                         }
719                         set {
720                                 ViewState ["StepNextButtonText"] = value;
721                         }
722                 }
723                 
724             [DefaultValueAttribute (ButtonType.Button)]
725                 public virtual ButtonType StepNextButtonType {
726                         get {
727                                 object v = ViewState ["StepNextButtonType"];
728                                 return v != null ? (ButtonType)v : ButtonType.Button;
729                         }
730                         set {
731                                 ViewState ["StepNextButtonType"] = value;
732                         }
733                 }
734                 
735             [UrlPropertyAttribute]
736             [DefaultValueAttribute ("")]
737             [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
738                 public virtual string StepPreviousButtonImageUrl {
739                         get {
740                                 object v = ViewState ["StepPreviousButtonImageUrl"];
741                                 return v != null ? (string)v : string.Empty;
742                         }
743                         set {
744                                 ViewState ["StepPreviousButtonImageUrl"] = value;
745                         }
746                 }
747                 
748             [DefaultValueAttribute (null)]
749             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
750             [NotifyParentPropertyAttribute (true)]
751             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
752                 public Style StepPreviousButtonStyle {
753                         get {
754                                 if (stepPreviousButtonStyle == null) {
755                                         stepPreviousButtonStyle = new Style ();
756                                         if (IsTrackingViewState)
757                                                 ((IStateManager)stepPreviousButtonStyle).TrackViewState ();
758                                 }
759                                 return stepPreviousButtonStyle;
760                         }
761                 }
762                 
763             [LocalizableAttribute (true)]
764                 public virtual string StepPreviousButtonText {
765                         get {
766                                 object v = ViewState ["StepPreviousButtonText"];
767                                 return v != null ? (string)v : "Previous";
768                         }
769                         set {
770                                 ViewState ["StepPreviousButtonText"] = value;
771                         }
772                 }
773                 
774             [DefaultValueAttribute (ButtonType.Button)]
775                 public virtual ButtonType StepPreviousButtonType {
776                         get {
777                                 object v = ViewState ["StepPreviousButtonType"];
778                                 return v != null ? (ButtonType)v : ButtonType.Button;
779                         }
780                         set {
781                                 ViewState ["StepPreviousButtonType"] = value;
782                         }
783                 }
784                 
785             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
786             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
787             [DefaultValueAttribute (null)]
788             [NotifyParentPropertyAttribute (true)]
789                 public TableItemStyle StepStyle {
790                         get {
791                                 if (stepStyle == null) {
792                                         stepStyle = new TableItemStyle ();
793                                         if (IsTrackingViewState)
794                                                 ((IStateManager)stepStyle).TrackViewState ();
795                                 }
796                                 return stepStyle;
797                         }
798                 }
799                 
800             [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
801             [EditorAttribute ("System.Web.UI.Design.WebControls.WizardStepCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
802             [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
803             [ThemeableAttribute (false)]
804                 public virtual WizardStepCollection WizardSteps {
805                         get {
806                                 if (steps == null)
807                                         steps = new WizardStepCollection (this);
808                                 return steps;
809                         }
810                 }
811
812                 protected virtual new HtmlTextWriterTag TagKey
813                 {
814                         get {
815                                 return HtmlTextWriterTag.Table;
816                         }
817                 }
818
819                 internal virtual ITemplate SideBarItemTemplate
820                 {
821                         get { return new SideBarButtonTemplate (this); }
822                 }
823                 
824                 public ICollection GetHistory ()
825                 {
826                         if (history == null)
827                                 history = new ArrayList ();
828                         return history;
829                 }
830                 
831                 public void MoveTo (WizardStepBase wizardStep)
832                 {
833                         if (wizardStep == null)
834                                 throw new ArgumentNullException ("wizardStep");
835                         
836                         int i = WizardSteps.IndexOf (wizardStep);
837                         if (i == -1)
838                                 throw new ArgumentException ("The provided wizard step does not belong to this wizard.");
839                         
840                         ActiveStepIndex = i;
841                 }
842                 
843                 public WizardStepType GetStepType (WizardStepBase wizardStep, int index)
844                 {
845                         if (wizardStep.StepType == WizardStepType.Auto) {
846                                 if ((index == WizardSteps.Count - 1) || 
847                                                 (WizardSteps.Count > 1 && 
848                                                 WizardSteps[WizardSteps.Count - 1].StepType == WizardStepType.Complete && 
849                                                 index == WizardSteps.Count - 2))
850                                         return WizardStepType.Finish;
851                                 else if (index == 0)
852                                         return WizardStepType.Start;
853                                 else
854                                         return WizardStepType.Step;
855                         } else
856                                 return wizardStep.StepType;
857                          
858                 }
859                 
860                 protected virtual bool AllowNavigationToStep (int index)
861                 {
862                         if ((index < 0 || index >= WizardSteps.Count) || history == null || !history.Contains (index))
863                                 return true;
864                         
865                         return WizardSteps [index].AllowReturn;
866                 } 
867                 
868                 protected internal override void OnInit (EventArgs e)
869                 {
870                         Page.RegisterRequiresControlState (this);
871                         base.OnInit (e);
872
873                         if (ActiveStepIndex == -1)
874                                 ActiveStepIndex = 0;
875
876                         EnsureChildControls ();
877                         
878                         inited = true;
879                 }
880                 
881                 protected override ControlCollection CreateControlCollection ()
882                 {
883                         ControlCollection col = new ControlCollection (this);
884                         col.SetReadonly (true);
885                         return col;
886                 }
887                 
888                 protected internal override void CreateChildControls ()
889                 {
890                         CreateControlHierarchy ();
891                 }
892 #if NET_4_0
893                 InvalidOperationException MakeLayoutException (string phName, string phID, string condition = null)
894                 {
895                         return new InvalidOperationException (
896                                 String.Format ("A {0} placeholder must be specified on Wizard '{1}'{2}. Specify a placeholder by setting a control's ID property to \"{3}\". The placeholder control must also specify runat=\"server\"",
897                                                phName, ID, condition, phID)
898                         );
899                 }
900
901                 void CreateControlHierarchy_LayoutTemplate (ITemplate layoutTemplate)
902                 {
903                         var layoutContainer = new WizardLayoutContainer ();
904                         ControlCollection controls = Controls;
905
906                         controls.SetReadonly (false);                   
907                         controls.Add (layoutContainer);
908                         controls.SetReadonly (true);
909                         
910                         layoutTemplate.InstantiateIn (layoutContainer);
911
912                         WizardStepCollection steps = WizardSteps;
913                         bool doRender = steps != null && steps.Count > 0;
914                         Control container, placeHolder;
915                         
916                         if (DisplaySideBar) {
917                                 placeHolder = layoutContainer.FindControl (SideBarPlaceholderId);
918                                 if (placeHolder == null)
919                                         throw MakeLayoutException ("sidebar", SideBarPlaceholderId, " when DisplaySideBar is set to true");
920
921                                 container = new Control ();
922                                 CreateSideBar (container);
923                                 ReplacePlaceHolder (layoutContainer, placeHolder, container);
924                         }
925
926                         ITemplate headerTemplate = HeaderTemplate;
927                         if (headerTemplate != null) {
928                                 placeHolder = layoutContainer.FindControl (HeaderPlaceholderId);
929                                 if (placeHolder == null)
930                                         throw MakeLayoutException ("header", HeaderPlaceholderId, " when HeaderTemplate is set");
931                                 
932                                 container = new Control ();
933                                 headerTemplate.InstantiateIn (container);
934                                 ReplacePlaceHolder (layoutContainer, placeHolder, container);
935                         }
936
937                         placeHolder = layoutContainer.FindControl (WizardStepPlaceholderId);
938                         if (placeHolder == null)
939                                 throw MakeLayoutException ("step", WizardStepPlaceholderId);
940                         
941                         customNavigation = null;
942                         multiView = new MultiView ();
943                         foreach (View v in steps) {
944                                 if (v is TemplatedWizardStep)
945                                         InstantiateTemplateStep ((TemplatedWizardStep) v);
946                                 multiView.Views.Add (v);
947                         }
948                         multiView.ActiveViewIndex = ActiveStepIndex;
949                         ReplacePlaceHolder (layoutContainer, placeHolder, multiView);
950
951                         placeHolder = layoutContainer.FindControl (NavigationPlaceholderId);
952                         if (placeHolder == null)
953                                 throw MakeLayoutException ("navigation", NavigationPlaceholderId);
954
955                         
956                         var contentTable = new Table ();
957                         contentTable.CellSpacing = 5;
958                         contentTable.CellPadding = 5;
959                         var row = new TableRow ();
960                         var cell = new TableCell ();
961                         cell.HorizontalAlign = HorizontalAlign.Right;
962
963                         container = new Control ();
964                         CreateButtonBar (container);
965                         
966                         row.Cells.Add (cell);
967                         contentTable.Rows.Add (row);
968                         ReplacePlaceHolder (layoutContainer, placeHolder, container);
969
970                         layoutContainer.Visible = doRender;
971                 }
972
973                 void ReplacePlaceHolder (WebControl container, Control placeHolder, Control replacement)
974                 {
975                         ControlCollection controls = container.Controls;
976                         int index = controls.IndexOf (placeHolder);
977                         controls.Remove (placeHolder);
978                         controls.AddAt (index, replacement);
979                 }
980 #endif
981                 protected virtual void CreateControlHierarchy ()
982                 {
983 #if NET_4_0
984                         ITemplate layoutTemplate = LayoutTemplate;
985                         if (layoutTemplate != null) {
986                                 CreateControlHierarchy_LayoutTemplate (layoutTemplate);
987                                 return;
988                         }
989 #endif
990                         styles.Clear ();
991
992                         wizardTable = new ContainedTable (this);
993
994                         Table contentTable = wizardTable;
995
996                         if (DisplaySideBar) {
997                                 contentTable = new Table ();
998                                 contentTable.CellPadding = 0;
999                                 contentTable.CellSpacing = 0;
1000                                 contentTable.Height = new Unit ("100%");
1001                                 contentTable.Width = new Unit ("100%");
1002
1003                                 TableRow row = new TableRow ();
1004
1005                                 TableCellNamingContainer sideBarCell = new TableCellNamingContainer (SkipLinkText, ClientID);
1006                                 sideBarCell.ID = "SideBarContainer";
1007                                 sideBarCell.ControlStyle.Height = Unit.Percentage (100);
1008                                 CreateSideBar (sideBarCell);
1009                                 row.Cells.Add (sideBarCell);
1010
1011                                 TableCell contentCell = new TableCell ();
1012                                 contentCell.Controls.Add (contentTable);
1013                                 contentCell.Height = new Unit ("100%");
1014                                 row.Cells.Add (contentCell);
1015
1016                                 wizardTable.Rows.Add (row);
1017                         }
1018
1019                         AddHeaderRow (contentTable);
1020
1021                         TableRow viewRow = new TableRow ();
1022                         TableCell viewCell = new TableCell ();
1023
1024                         customNavigation = null;
1025                         multiView = new MultiView ();
1026                         foreach (View v in WizardSteps) {
1027                                 if (v is TemplatedWizardStep)
1028                                         InstantiateTemplateStep ((TemplatedWizardStep) v);
1029                                 multiView.Views.Add (v);
1030                         }
1031                         multiView.ActiveViewIndex = ActiveStepIndex;
1032
1033                         RegisterApplyStyle (viewCell, StepStyle);
1034                         viewCell.Controls.Add (multiView);
1035                         viewRow.Cells.Add (viewCell);
1036                         viewRow.Height = new Unit ("100%");
1037                         contentTable.Rows.Add (viewRow);
1038
1039                         TableRow buttonRow = new TableRow ();
1040                         _navigationCell = new TableCell ();
1041                         _navigationCell.HorizontalAlign = HorizontalAlign.Right;
1042                         RegisterApplyStyle (_navigationCell, NavigationStyle);
1043                         CreateButtonBar (_navigationCell);
1044                         buttonRow.Cells.Add (_navigationCell);
1045                         contentTable.Rows.Add (buttonRow);
1046
1047                         Controls.SetReadonly (false);
1048                         Controls.Add (wizardTable);
1049                         Controls.SetReadonly (true);
1050                 }
1051
1052                 internal virtual void InstantiateTemplateStep(TemplatedWizardStep step)
1053                 {
1054                         BaseWizardContainer contentTemplateContainer = new BaseWizardContainer ();
1055
1056                         if (step.ContentTemplate != null)
1057                                 step.ContentTemplate.InstantiateIn (contentTemplateContainer.InnerCell);
1058
1059                         step.ContentTemplateContainer = contentTemplateContainer;
1060                         step.Controls.Clear ();
1061                         step.Controls.Add (contentTemplateContainer);
1062
1063                         BaseWizardNavigationContainer customNavigationTemplateContainer = new BaseWizardNavigationContainer ();
1064
1065                         if (step.CustomNavigationTemplate != null) {
1066                                 step.CustomNavigationTemplate.InstantiateIn (customNavigationTemplateContainer);
1067                                 RegisterCustomNavigation (step, customNavigationTemplateContainer);
1068                         }
1069                         step.CustomNavigationTemplateContainer = customNavigationTemplateContainer;
1070                 }
1071
1072                 internal void RegisterCustomNavigation (TemplatedWizardStep step, BaseWizardNavigationContainer customNavigationTemplateContainer)
1073                 {
1074                         if (customNavigation == null)
1075                                 customNavigation = new Hashtable ();
1076                         customNavigation [step] = customNavigationTemplateContainer;
1077                 }
1078                 
1079                 void CreateButtonBar (Control container)
1080                 {
1081                         if(customNavigation != null && customNavigation.Values.Count > 0 ) {
1082                                 int i = 0;
1083                                 foreach (Control customNavigationTemplateContainer in customNavigation.Values) {
1084                                         customNavigationTemplateContainer.ID = "CustomNavigationTemplateContainerID" + i++;
1085                                         container.Controls.Add (customNavigationTemplateContainer);
1086                                 }
1087                         }
1088                         
1089                         //
1090                         // StartNavContainer
1091                         //
1092                         _startNavContainer = new StartNavigationContainer (this);
1093                         _startNavContainer.ID = "StartNavigationTemplateContainerID";
1094                         if (startNavigationTemplate != null)
1095                                 startNavigationTemplate.InstantiateIn (_startNavContainer);
1096                         else {
1097                                 TableRow row;
1098                                 AddNavButtonsTable (_startNavContainer, out row);
1099                                 AddButtonCell (row, CreateButtonSet (StartNextButtonIDShort, MoveNextCommandName));
1100                                 AddButtonCell (row, CreateButtonSet (CancelButtonIDShort, CancelCommandName, false));
1101                                 _startNavContainer.ConfirmDefaultTemplate ();
1102                         }
1103                         container.Controls.Add (_startNavContainer);
1104
1105                         //
1106                         // StepNavContainer
1107                         //
1108                         _stepNavContainer = new StepNavigationContainer (this);
1109                         _stepNavContainer.ID = "StepNavigationTemplateContainerID";
1110                         if (stepNavigationTemplate != null)
1111                                 stepNavigationTemplate.InstantiateIn (_stepNavContainer);
1112                         else {
1113                                 TableRow row;
1114                                 AddNavButtonsTable (_stepNavContainer, out row);
1115                                 AddButtonCell (row, CreateButtonSet (StepPreviousButtonIDShort, MovePreviousCommandName, false));
1116                                 AddButtonCell (row, CreateButtonSet (StepNextButtonIDShort, MoveNextCommandName));
1117                                 AddButtonCell (row, CreateButtonSet (CancelButtonIDShort, CancelCommandName, false));
1118                                 _stepNavContainer.ConfirmDefaultTemplate ();
1119                         }
1120                         container.Controls.Add (_stepNavContainer);
1121
1122                         //
1123                         // StepNavContainer
1124                         //
1125                         _finishNavContainer = new FinishNavigationContainer (this);
1126                         _finishNavContainer.ID = "FinishNavigationTemplateContainerID";
1127                         if (finishNavigationTemplate != null)
1128                                 finishNavigationTemplate.InstantiateIn (_finishNavContainer);
1129                         else {
1130                                 TableRow row;
1131                                 AddNavButtonsTable (_finishNavContainer, out row);
1132                                 AddButtonCell (row, CreateButtonSet (FinishPreviousButtonIDShort, MovePreviousCommandName, false));
1133                                 AddButtonCell (row, CreateButtonSet (FinishButtonIDShort, MoveCompleteCommandName));
1134                                 AddButtonCell (row, CreateButtonSet (CancelButtonIDShort, CancelCommandName, false));
1135                                 _finishNavContainer.ConfirmDefaultTemplate ();
1136                         }
1137                         container.Controls.Add (_finishNavContainer);
1138                 }
1139
1140                 static void AddNavButtonsTable (BaseWizardNavigationContainer container, out TableRow row)
1141                 {
1142                         Table t = new Table ();
1143                         t.CellPadding = 5;
1144                         t.CellSpacing = 5;
1145                         row = new TableRow ();
1146                         t.Rows.Add (row);
1147                         container.Controls.Add (t);
1148                 }
1149
1150                 Control [] CreateButtonSet (string id, string command)
1151                 {
1152                         return CreateButtonSet (id, command, true, null);
1153                 }
1154
1155                 Control [] CreateButtonSet (string id, string command, bool causesValidation)
1156                 {
1157                         return CreateButtonSet (id, command, causesValidation, null);
1158                 }
1159
1160                 internal Control [] CreateButtonSet (string id, string command, bool causesValidation, string validationGroup)
1161                 {
1162                         return new Control [] { 
1163                                 CreateButton ( id + ButtonType.Button,  command, ButtonType.Button, causesValidation, validationGroup),
1164                                 CreateButton ( id + ButtonType.Image,  command, ButtonType.Image, causesValidation, validationGroup),
1165                                 CreateButton ( id + ButtonType.Link,  command, ButtonType.Link, causesValidation, validationGroup)
1166                                 };
1167                 }
1168                 
1169                 Control CreateButton (string id, string command, ButtonType type, bool causesValidation, string validationGroup)
1170                 {
1171                         WebControl b;
1172                         switch (type) {
1173                         case ButtonType.Button:
1174                                 b = CreateStandardButton ();
1175                                 break;
1176                         case ButtonType.Image:
1177                                 b = CreateImageButton (null);
1178                                 break;
1179                         case ButtonType.Link:
1180                                 b = CreateLinkButton ();
1181                                 break;
1182                         default:
1183                                 throw new ArgumentOutOfRangeException ("type");
1184                         }
1185
1186                         b.ID = id;
1187                         b.EnableTheming = false;
1188                         ((IButtonControl) b).CommandName = command;
1189                         ((IButtonControl) b).CausesValidation = causesValidation;
1190                         if(!String.IsNullOrEmpty(validationGroup))
1191                                 ((IButtonControl) b).ValidationGroup = validationGroup;
1192
1193                         RegisterApplyStyle (b, NavigationButtonStyle);
1194
1195                         return b;
1196                 }
1197
1198                 WebControl CreateStandardButton () {
1199                         Button btn = new Button ();
1200                         return btn;
1201                 }
1202
1203                 WebControl CreateImageButton (string imageUrl) {
1204                         ImageButton img = new ImageButton ();
1205                         img.ImageUrl = imageUrl;
1206                         return img;
1207                 }
1208
1209                 WebControl CreateLinkButton () {
1210                         LinkButton link = new LinkButton ();
1211                         return link;
1212                 }
1213
1214                 void AddButtonCell (TableRow row, params Control[] controls)
1215                 {
1216                         TableCell cell = new TableCell ();
1217                         cell.HorizontalAlign = HorizontalAlign.Right;
1218                         for (int i = 0; i < controls.Length; i++)
1219                                 cell.Controls.Add (controls [i]);
1220                         row.Cells.Add (cell);
1221                 }
1222                 
1223                 void CreateSideBar (Control container)
1224                 {
1225                         WebControl wctl = container as WebControl;
1226                         if (wctl != null)
1227                                 RegisterApplyStyle (wctl, SideBarStyle);
1228
1229                         if (sideBarTemplate != null) {
1230                                 sideBarTemplate.InstantiateIn (container);
1231                                 stepDatalist = container.FindControl (DataListID) as DataList;
1232                                 if (stepDatalist == null)
1233                                         throw new InvalidOperationException ("The side bar template must contain a DataList control with id '" + DataListID + "'.");
1234                                 stepDatalist.ItemDataBound += new DataListItemEventHandler(StepDatalistItemDataBound);
1235                         } else {
1236                                 stepDatalist = new DataList ();
1237                                 stepDatalist.ID = DataListID;
1238                                 stepDatalist.SelectedItemStyle.Font.Bold = true;
1239                                 stepDatalist.ItemTemplate = SideBarItemTemplate;
1240                                 container.Controls.Add (stepDatalist);
1241                         }
1242
1243                         stepDatalist.ItemCommand += new DataListCommandEventHandler (StepDatalistItemCommand);
1244                         stepDatalist.CellSpacing = 0;
1245                         stepDatalist.DataSource = WizardSteps;
1246                         stepDatalist.SelectedIndex = ActiveStepIndex;
1247                         stepDatalist.DataBind ();
1248                 }
1249
1250                 void StepDatalistItemCommand (object sender, DataListCommandEventArgs e)
1251                 {
1252                         WizardNavigationEventArgs arg = new WizardNavigationEventArgs (ActiveStepIndex, Convert.ToInt32 (e.CommandArgument));
1253                         OnSideBarButtonClick (arg);
1254
1255                         if (!arg.Cancel)
1256                                 ActiveStepIndex = arg.NextStepIndex;
1257                 }
1258
1259                 void StepDatalistItemDataBound (object sender, DataListItemEventArgs e)
1260                 {
1261                         if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.SelectedItem) {
1262                                 IButtonControl button = (IButtonControl) e.Item.FindControl (SideBarButtonID);
1263                                 if (button == null)
1264                                         throw new InvalidOperationException ("SideBarList control must contain an IButtonControl with ID " + SideBarButtonID + " in every item template, this maybe include ItemTemplate, EditItemTemplate, SelectedItemTemplate or AlternatingItemTemplate if they exist.");
1265
1266                                 WizardStepBase step = (WizardStepBase) e.Item.DataItem;
1267
1268                                 if (button is Button)
1269                                         ((Button) button).UseSubmitBehavior = false;
1270
1271                                 button.CommandName = Wizard.MoveToCommandName;
1272                                 button.CommandArgument = WizardSteps.IndexOf (step).ToString ();
1273                                 button.Text = step.Name;
1274                                 if (step.StepType == WizardStepType.Complete && button is WebControl)
1275                                         ((WebControl) button).Enabled = false;
1276                         }
1277                 }
1278                 
1279                 void AddHeaderRow (Table table)
1280                 {
1281                         TableRow row = new TableRow ();
1282                         _headerCell = new WizardHeaderCell ();
1283                         _headerCell.ID = "HeaderContainer";
1284                         RegisterApplyStyle (_headerCell, HeaderStyle);
1285                         if (headerTemplate != null) {
1286                                 headerTemplate.InstantiateIn (_headerCell);
1287                                 _headerCell.ConfirmInitState ();
1288                         }
1289                         row.Cells.Add (_headerCell);
1290                         table.Rows.Add (row);
1291                 }
1292
1293                 internal void RegisterApplyStyle (WebControl control, Style style)
1294                 {
1295                         styles.Add (new object [] { control, style });
1296                 }
1297                 
1298                 protected override Style CreateControlStyle ()
1299                 {
1300                         TableStyle style = new TableStyle ();
1301                         style.CellPadding = 0;
1302                         style.CellSpacing = 0;
1303                         return style;
1304                 }
1305
1306                 protected override IDictionary GetDesignModeState ()
1307                 {
1308                         throw new NotImplementedException ();
1309                 }
1310                 
1311                 protected internal override void LoadControlState (object ob)
1312                 {
1313                         if (ob == null) return;
1314                         object[] state = (object[]) ob;
1315                         base.LoadControlState (state[0]);
1316                         activeStepIndex = (int) state[1];
1317                         history = (ArrayList) state[2];
1318                 }
1319                 
1320                 protected internal override object SaveControlState ()
1321                 {
1322                         if (GetHistory ().Count == 0 || (int) history [0] != ActiveStepIndex)
1323                                 history.Insert (0, ActiveStepIndex);
1324
1325                         object bstate = base.SaveControlState ();
1326                         return new object[] {
1327                                 bstate, activeStepIndex, history
1328                         };
1329                 }
1330                 
1331                 protected override void LoadViewState (object savedState)
1332                 {
1333                         if (savedState == null) {
1334                                 base.LoadViewState (null);
1335                                 return;
1336                         }
1337                         
1338                         object[] states = (object[]) savedState;
1339                         base.LoadViewState (states [0]);
1340                         
1341                         if (states[1] != null) ((IStateManager)StepStyle).LoadViewState (states[1]);
1342                         if (states[2] != null) ((IStateManager)SideBarStyle).LoadViewState (states[2]);
1343                         if (states[3] != null) ((IStateManager)HeaderStyle).LoadViewState (states[3]);
1344                         if (states[4] != null) ((IStateManager)NavigationStyle).LoadViewState (states[4]);
1345                         if (states[5] != null) ((IStateManager)SideBarButtonStyle).LoadViewState (states[5]);
1346                         if (states[6] != null) ((IStateManager)CancelButtonStyle).LoadViewState (states[6]);
1347                         if (states[7] != null) ((IStateManager)FinishCompleteButtonStyle).LoadViewState (states[7]);
1348                         if (states[8] != null) ((IStateManager)FinishPreviousButtonStyle).LoadViewState (states[8]);
1349                         if (states[9] != null) ((IStateManager)StartNextButtonStyle).LoadViewState (states[9]);
1350                         if (states[10] != null) ((IStateManager)StepNextButtonStyle).LoadViewState (states[10]);
1351                         if (states[11] != null) ((IStateManager)StepPreviousButtonStyle).LoadViewState (states[11]);
1352                         if (states[12] != null) ((IStateManager)NavigationButtonStyle).LoadViewState (states[12]);
1353                         if (states [13] != null)
1354                                 ControlStyle.LoadViewState (states [13]);
1355                 }
1356                 
1357                 protected override object SaveViewState ()
1358                 {
1359                         object [] state = new object [14];
1360                         state [0] = base.SaveViewState ();
1361                         
1362                         if (stepStyle != null) state [1] = ((IStateManager)stepStyle).SaveViewState ();
1363                         if (sideBarStyle != null) state [2] = ((IStateManager)sideBarStyle).SaveViewState ();
1364                         if (headerStyle != null) state [3] = ((IStateManager)headerStyle).SaveViewState ();
1365                         if (navigationStyle != null) state [4] = ((IStateManager)navigationStyle).SaveViewState ();
1366                         if (sideBarButtonStyle != null) state [5] = ((IStateManager)sideBarButtonStyle).SaveViewState ();
1367                         if (cancelButtonStyle != null) state [6] = ((IStateManager)cancelButtonStyle).SaveViewState ();
1368                         if (finishCompleteButtonStyle != null) state [7] = ((IStateManager)finishCompleteButtonStyle).SaveViewState ();
1369                         if (finishPreviousButtonStyle != null) state [8] = ((IStateManager)finishPreviousButtonStyle).SaveViewState ();
1370                         if (startNextButtonStyle != null) state [9] = ((IStateManager)startNextButtonStyle).SaveViewState ();
1371                         if (stepNextButtonStyle != null) state [10] = ((IStateManager)stepNextButtonStyle).SaveViewState ();
1372                         if (stepPreviousButtonStyle != null) state [11] = ((IStateManager)stepPreviousButtonStyle).SaveViewState ();
1373                         if (navigationButtonStyle != null) state [12] = ((IStateManager)navigationButtonStyle).SaveViewState ();
1374                         if (ControlStyleCreated)
1375                                 state [13] = ControlStyle.SaveViewState ();
1376         
1377                         for (int n=0; n<state.Length; n++)
1378                                 if (state [n] != null) return state;
1379                         return null;
1380                 }
1381                 
1382                 protected override void TrackViewState ()
1383                 {
1384                         base.TrackViewState();
1385                         if (stepStyle != null) ((IStateManager)stepStyle).TrackViewState();
1386                         if (sideBarStyle != null) ((IStateManager)sideBarStyle).TrackViewState();
1387                         if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1388                         if (navigationStyle != null) ((IStateManager)navigationStyle).TrackViewState();
1389                         if (sideBarButtonStyle != null) ((IStateManager)sideBarButtonStyle).TrackViewState();
1390                         if (cancelButtonStyle != null) ((IStateManager)cancelButtonStyle).TrackViewState();
1391                         if (finishCompleteButtonStyle != null) ((IStateManager)finishCompleteButtonStyle).TrackViewState();
1392                         if (finishPreviousButtonStyle != null) ((IStateManager)finishPreviousButtonStyle).TrackViewState();
1393                         if (startNextButtonStyle != null) ((IStateManager)startNextButtonStyle).TrackViewState();
1394                         if (stepNextButtonStyle != null) ((IStateManager)stepNextButtonStyle).TrackViewState();
1395                         if (stepPreviousButtonStyle != null) ((IStateManager)stepPreviousButtonStyle).TrackViewState();
1396                         if (navigationButtonStyle != null) ((IStateManager)navigationButtonStyle).TrackViewState();
1397                         if (ControlStyleCreated)
1398                                 ControlStyle.TrackViewState ();
1399                 }
1400                 
1401                 protected internal void RegisterCommandEvents (IButtonControl button)
1402                 {
1403                         button.Command += ProcessCommand;
1404                 }
1405                 
1406                 void ProcessCommand (object sender, CommandEventArgs args)
1407                 {
1408                         Control c = sender as Control;
1409                         if (c != null) {
1410                                 switch (c.ID) {
1411                                         case "CancelButton":
1412                                                 ProcessEvent ("Cancel", null);
1413                                                 return;
1414                                         case "FinishButton":
1415                                                 ProcessEvent ("MoveComplete", null);
1416                                                 return;
1417                                         case "StepPreviousButton":
1418                                         case "FinishPreviousButton":
1419                                                 ProcessEvent ("MovePrevious", null);
1420                                                 return;
1421                                         case "StartNextButton":
1422                                         case "StepNextButton":
1423                                                 ProcessEvent ("MoveNext", null);
1424                                                 return;
1425                                 }
1426                         }
1427                         ProcessEvent (args.CommandName, args.CommandArgument as string);
1428                 }
1429
1430                 protected override bool OnBubbleEvent (object source, EventArgs e)
1431                 {
1432                         CommandEventArgs args = e as CommandEventArgs;
1433                         if (args != null) {
1434                                 ProcessEvent (args.CommandName, args.CommandArgument as string);
1435                                 return true;
1436                         }
1437                         return base.OnBubbleEvent (source, e);
1438                 }
1439                 
1440                 void ProcessEvent (string commandName, string commandArg)
1441                 {
1442                         switch (commandName) {
1443                                 case "Cancel":
1444                                         if (CancelDestinationPageUrl.Length > 0)
1445                                                 Context.Response.Redirect (CancelDestinationPageUrl);
1446                                         else
1447                                                 OnCancelButtonClick (EventArgs.Empty);
1448                                         break;
1449
1450                                 case "MoveComplete":
1451                                         int next = -1;
1452                                         for (int n=0; n<WizardSteps.Count; n++) {
1453                                                 if (WizardSteps [n].StepType == WizardStepType.Complete) {
1454                                                         next = n;
1455                                                         break;
1456                                                 }
1457                                         }
1458
1459                                         if (next == -1 && ActiveStepIndex == WizardSteps.Count - 1)
1460                                                 next = ActiveStepIndex;
1461
1462                                         WizardNavigationEventArgs navArgs = new WizardNavigationEventArgs (ActiveStepIndex, next);
1463                                         OnFinishButtonClick (navArgs);
1464
1465                                         if (FinishDestinationPageUrl.Length > 0) {
1466                                                 Context.Response.Redirect (FinishDestinationPageUrl);
1467                                                 return;
1468                                         }
1469
1470                                         if (next != -1 && !navArgs.Cancel)
1471                                                 ActiveStepIndex = next;
1472
1473                                         break;
1474                                         
1475                                 case "MoveNext":
1476                                         if (ActiveStepIndex < WizardSteps.Count - 1) {
1477                                                 WizardNavigationEventArgs args = new WizardNavigationEventArgs (ActiveStepIndex, ActiveStepIndex + 1);
1478                                                 int curStep = ActiveStepIndex;
1479                                                 OnNextButtonClick (args);
1480                                                 if (!args.Cancel && curStep == activeStepIndex)
1481                                                         ActiveStepIndex++;
1482                                         }
1483                                         break;
1484                                                         
1485                                 case "MovePrevious":
1486                                         if (ActiveStepIndex > 0) {
1487                                                 WizardNavigationEventArgs args = new WizardNavigationEventArgs (ActiveStepIndex, ActiveStepIndex - 1);
1488                                                 int curStep = ActiveStepIndex;
1489                                                 OnPreviousButtonClick (args);
1490                                                 if (!args.Cancel) {
1491                                                         if (curStep == activeStepIndex)
1492                                                                 ActiveStepIndex--;
1493                                                         if (history != null && activeStepIndex < curStep)
1494                                                                 history.Remove (curStep);
1495                                                 }
1496                                         }
1497                                         break;
1498                                         
1499                                 case "Move":
1500                                         int newb = int.Parse (commandArg);
1501                                         ActiveStepIndex = newb;
1502                                         break;
1503                         }
1504                 }
1505                 
1506                 internal void UpdateViews ()
1507                 {
1508                         ChildControlsCreated = false;
1509                 }
1510                 
1511                 protected internal override void Render (HtmlTextWriter writer)
1512                 {
1513                         PrepareControlHierarchy ();
1514 #if NET_4_0
1515                         if (LayoutTemplate == null)
1516 #endif
1517                                 wizardTable.Render (writer);
1518 #if NET_4_0
1519                         else
1520                                 RenderChildren (writer);
1521 #endif
1522                 }
1523
1524                 void PrepareControlHierarchy ()
1525                 {
1526 #if NET_4_0
1527                         if (LayoutTemplate == null) {
1528 #endif
1529                                 // header
1530                                 if (!_headerCell.Initialized) {
1531                                         if (String.IsNullOrEmpty (HeaderText))
1532                                                 _headerCell.Parent.Visible = false;
1533                                         else
1534                                                 _headerCell.Text = HeaderText;
1535                                 }
1536
1537                                 if (ActiveStep.StepType == WizardStepType.Complete)
1538                                         _headerCell.Parent.Visible = false;
1539 #if NET_4_0
1540                         } else {
1541                                 WizardStepCollection steps = WizardSteps;
1542
1543                                 if (steps == null || steps.Count == 0)
1544                                         return;
1545                         }
1546 #endif
1547                         
1548                         // sidebar
1549                         if (stepDatalist != null) {
1550                                 stepDatalist.SelectedIndex = ActiveStepIndex;
1551                                 stepDatalist.DataBind ();
1552
1553                                 if (ActiveStep.StepType == WizardStepType.Complete)
1554                                         stepDatalist.NamingContainer.Visible = false;
1555                         }
1556
1557                         // content
1558                         TemplatedWizardStep templateStep = ActiveStep as TemplatedWizardStep;
1559                         if (templateStep != null) {
1560                                 BaseWizardContainer contentContainer = templateStep.ContentTemplateContainer as BaseWizardContainer;
1561                                 if (contentContainer != null)
1562                                         contentContainer.PrepareControlHierarchy ();
1563                         }
1564
1565                         // navigation
1566                         if (customNavigation != null) {
1567                                 foreach (Control c in customNavigation.Values)
1568                                         c.Visible = false;
1569                         }
1570                         _startNavContainer.Visible = false;
1571                         _stepNavContainer.Visible = false;
1572                         _finishNavContainer.Visible = false;
1573
1574                         BaseWizardNavigationContainer currentNavContainer = GetCurrentNavContainer ();
1575                         if (currentNavContainer == null) {
1576                                 if (_navigationCell != null)
1577                                         _navigationCell.Parent.Visible = false;
1578                         } else {
1579                                 currentNavContainer.Visible = true;
1580                                 currentNavContainer.PrepareControlHierarchy ();
1581                                 if (_navigationCell != null && !currentNavContainer.Visible)
1582                                         _navigationCell.Parent.Visible = false;
1583                         }
1584
1585                         foreach (object [] styleDef in styles)
1586                                 ((WebControl) styleDef [0]).ApplyStyle ((Style) styleDef [1]);
1587                 }
1588
1589                 BaseWizardNavigationContainer GetCurrentNavContainer ()
1590                 {
1591                         if (customNavigation != null && customNavigation [ActiveStep] != null) {
1592                                 return (BaseWizardNavigationContainer) customNavigation [ActiveStep];
1593                         }
1594                         else {
1595                                 WizardStepType stepType = GetStepType (ActiveStep, ActiveStepIndex);
1596                                 switch (stepType) {
1597                                 case WizardStepType.Start:
1598                                         return _startNavContainer;
1599                                 case WizardStepType.Step:
1600                                         return _stepNavContainer;
1601                                 case WizardStepType.Finish:
1602                                         return _finishNavContainer;
1603                                 default:
1604                                         return null;
1605                                 }
1606                         }
1607                 }
1608
1609                 sealed class TableCellNamingContainer : TableCell, INamingContainer, INonBindingContainer
1610                 {
1611                         string skipLinkText;
1612                         string clientId;
1613                         bool haveSkipLink;
1614                         
1615                         protected internal override void RenderChildren (HtmlTextWriter writer)
1616                         {
1617                                 if (haveSkipLink) {
1618                                         // <a href="#ID_SkipLink">
1619                                         writer.AddAttribute (HtmlTextWriterAttribute.Href, "#" + clientId + "_SkipLink");
1620                                         writer.RenderBeginTag (HtmlTextWriterTag.A);
1621
1622                                         // <img alt="" height="0" width="0" src="" style="border-width:0px;"/>
1623                                         writer.AddAttribute (HtmlTextWriterAttribute.Alt, skipLinkText);
1624                                         writer.AddAttribute (HtmlTextWriterAttribute.Height, "0");
1625                                         writer.AddAttribute (HtmlTextWriterAttribute.Width, "0");
1626
1627                                         Page page = Page;
1628                                         ClientScriptManager csm;
1629                                         
1630                                         if (page != null)
1631                                                 csm = page.ClientScript;
1632                                         else
1633                                                 csm = new ClientScriptManager (null);
1634                                         writer.AddAttribute (HtmlTextWriterAttribute.Src, csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif"));
1635                                         writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0px");
1636                                         writer.RenderBeginTag (HtmlTextWriterTag.Img);
1637                                         writer.RenderEndTag ();
1638                                         
1639                                         writer.RenderEndTag (); // </a>
1640                                 }
1641                                 
1642                                 base.RenderChildren (writer);
1643
1644                                 if (haveSkipLink) {
1645                                         writer.AddAttribute (HtmlTextWriterAttribute.Id, "SkipLink");
1646                                         writer.RenderBeginTag (HtmlTextWriterTag.A);
1647                                         writer.RenderEndTag ();
1648                                 }
1649                         }
1650                         
1651                         public TableCellNamingContainer (string skipLinkText, string clientId)
1652                         {
1653                                 this.skipLinkText = skipLinkText;
1654                                 this.clientId = clientId;
1655                                 this.haveSkipLink = !String.IsNullOrEmpty (skipLinkText);
1656                         }
1657                 }
1658
1659                 sealed class SideBarButtonTemplate: ITemplate
1660                 {
1661                         Wizard wizard;
1662                         
1663                         public SideBarButtonTemplate (Wizard wizard)
1664                         {
1665                                 this.wizard = wizard;
1666                         }
1667                         
1668                         public void InstantiateIn (Control control)
1669                         {
1670                                 LinkButton b = new LinkButton ();
1671                                 wizard.RegisterApplyStyle (b, wizard.SideBarButtonStyle);
1672                                 control.Controls.Add (b);
1673                                 control.DataBinding += Bound;
1674                         }
1675                         
1676                         void Bound (object s, EventArgs args)
1677                         {
1678                                 WizardStepBase step = DataBinder.GetDataItem (s) as WizardStepBase;
1679                                 if (step != null) {
1680                                         DataListItem c = (DataListItem) s;
1681                                         LinkButton b = (LinkButton) c.Controls[0];
1682                                         b.ID = SideBarButtonID;
1683                                         b.CommandName = Wizard.MoveToCommandName;
1684                                         b.CommandArgument = wizard.WizardSteps.IndexOf (step).ToString ();
1685                                         b.Text = step.Name;
1686                                         if (step.StepType == WizardStepType.Complete)
1687                                                 b.Enabled = false;
1688                                 }
1689                         }
1690                 }
1691
1692                 class WizardHeaderCell : TableCell, INamingContainer, INonBindingContainer
1693                 {
1694                         bool _initialized;
1695
1696                         public bool Initialized {
1697                                 get { return _initialized; }
1698                         }
1699                         
1700                         public WizardHeaderCell ()
1701                         {
1702                         }
1703                         
1704                         public void ConfirmInitState ()
1705                         {
1706                                 _initialized = true;
1707                         }
1708                 }
1709
1710                 internal abstract class DefaultNavigationContainer : BaseWizardNavigationContainer
1711                 {
1712                         bool _isDefault;
1713                         Wizard _wizard;
1714
1715                         protected Wizard Wizard {
1716                                 get { return _wizard; }
1717                         }
1718
1719                         protected DefaultNavigationContainer (Wizard wizard)
1720                         {
1721                                 _wizard = wizard;
1722                         }
1723
1724                         public override sealed void PrepareControlHierarchy ()
1725                         {
1726                                 if (_isDefault)
1727                                         UpdateState ();
1728                         }
1729
1730                         protected abstract void UpdateState ();
1731
1732                         public void ConfirmDefaultTemplate ()
1733                         {
1734                                 _isDefault = true;
1735                         }
1736
1737                         protected void UpdateNavButtonState (string id, string text, string image, Style style)
1738                         {
1739                                 WebControl b = (WebControl) FindControl (id);
1740                                 foreach (Control c in b.Parent.Controls)
1741                                         c.Visible = b == c;
1742
1743                                 ((IButtonControl) b).Text = text;
1744                                 ImageButton imgbtn = b as ImageButton;
1745                                 if (imgbtn != null)
1746                                         imgbtn.ImageUrl = image;
1747
1748                                 b.ApplyStyle (style);
1749                         }
1750                 }
1751
1752                 sealed class StartNavigationContainer : DefaultNavigationContainer
1753                 {
1754                         public StartNavigationContainer (Wizard wizard)
1755                                 : base (wizard)
1756                         {
1757                         }
1758
1759                         protected override void UpdateState ()
1760                         {
1761                                 bool visible = false;
1762                                 
1763                                 // next
1764                                 if (Wizard.AllowNavigationToStep (Wizard.ActiveStepIndex + 1)) {
1765                                         visible = true;
1766                                         UpdateNavButtonState (Wizard.StartNextButtonIDShort + Wizard.StartNextButtonType, Wizard.StartNextButtonText, Wizard.StartNextButtonImageUrl, Wizard.StartNextButtonStyle);
1767                                 } else
1768                                         ((Table) Controls [0]).Rows [0].Cells [0].Visible = false;
1769
1770                                 // cancel
1771                                 if (Wizard.DisplayCancelButton) {
1772                                         visible = true;
1773                                         UpdateNavButtonState (Wizard.CancelButtonIDShort + Wizard.CancelButtonType, Wizard.CancelButtonText, Wizard.CancelButtonImageUrl, Wizard.CancelButtonStyle);
1774                                 } else
1775                                         ((Table) Controls [0]).Rows [0].Cells [1].Visible = false;
1776
1777                                 Visible = visible;
1778                         }
1779                 }
1780
1781                 sealed class StepNavigationContainer : DefaultNavigationContainer
1782                 {
1783                         public StepNavigationContainer (Wizard wizard)
1784                                 : base (wizard)
1785                         {
1786                         }
1787
1788                         protected override void UpdateState ()
1789                         {
1790                                 bool visible = false;
1791                                 // previous
1792                                 if (Wizard.AllowNavigationToStep (Wizard.ActiveStepIndex - 1)) {
1793                                         visible = true;
1794                                         UpdateNavButtonState (Wizard.StepPreviousButtonIDShort + Wizard.StepPreviousButtonType, Wizard.StepPreviousButtonText, Wizard.StepPreviousButtonImageUrl, Wizard.StepPreviousButtonStyle);
1795                                 } else
1796                                         ((Table) Controls [0]).Rows [0].Cells [0].Visible = false;
1797
1798                                 // next
1799                                 if (Wizard.AllowNavigationToStep (Wizard.ActiveStepIndex + 1)) {
1800                                         visible = true;
1801                                         UpdateNavButtonState (Wizard.StepNextButtonIDShort + Wizard.StepNextButtonType, Wizard.StepNextButtonText, Wizard.StepNextButtonImageUrl, Wizard.StepNextButtonStyle);
1802                                 } else
1803                                         ((Table) Controls [0]).Rows [0].Cells [1].Visible = false;
1804
1805                                 // cancel
1806                                 if (Wizard.DisplayCancelButton) {
1807                                         visible = true;
1808                                         UpdateNavButtonState (Wizard.CancelButtonIDShort + Wizard.CancelButtonType, Wizard.CancelButtonText, Wizard.CancelButtonImageUrl, Wizard.CancelButtonStyle);
1809                                 } else
1810                                         ((Table) Controls [0]).Rows [0].Cells [2].Visible = false;
1811                                 
1812                                 Visible = visible;
1813                         }
1814                 }
1815
1816                 sealed class FinishNavigationContainer : DefaultNavigationContainer
1817                 {
1818                         public FinishNavigationContainer (Wizard wizard)
1819                                 : base (wizard)
1820                         {
1821                         }
1822
1823                         protected override void UpdateState ()
1824                         {
1825                                 // previous
1826                                 int previous = Wizard.ActiveStepIndex - 1;
1827                                 if (previous >= 0 && Wizard.AllowNavigationToStep (previous)) {
1828                                         UpdateNavButtonState (Wizard.FinishPreviousButtonIDShort + Wizard.FinishPreviousButtonType, Wizard.FinishPreviousButtonText, Wizard.FinishPreviousButtonImageUrl, Wizard.FinishPreviousButtonStyle);
1829                                 } else
1830                                         ((Table) Controls [0]).Rows [0].Cells [0].Visible = false;
1831
1832                                 // finish
1833                                 UpdateNavButtonState (Wizard.FinishButtonIDShort + Wizard.FinishCompleteButtonType, Wizard.FinishCompleteButtonText, Wizard.FinishCompleteButtonImageUrl, Wizard.FinishCompleteButtonStyle);
1834
1835                                 // cancel
1836                                 if (Wizard.DisplayCancelButton) {
1837                                         UpdateNavButtonState (Wizard.CancelButtonIDShort + Wizard.CancelButtonType, Wizard.CancelButtonText, Wizard.CancelButtonImageUrl, Wizard.CancelButtonStyle);
1838                                 } else
1839                                         ((Table) Controls [0]).Rows [0].Cells [2].Visible = false;
1840                         }
1841                 }
1842
1843                 internal class BaseWizardContainer : Table, INamingContainer, INonBindingContainer
1844                 {
1845                         public TableCell InnerCell {
1846                                 get { return Rows [0].Cells [0]; }
1847                         }
1848
1849                         internal BaseWizardContainer ()
1850                         {
1851                                 InitTable ();
1852                         }
1853
1854                         void InitTable () {
1855                                 TableRow row = new TableRow ();
1856                                 TableCell cell = new TableCell ();
1857
1858                                 cell.ControlStyle.Width = Unit.Percentage (100);
1859                                 cell.ControlStyle.Height = Unit.Percentage (100);
1860
1861                                 row.Cells.Add (cell);
1862
1863                                 this.ControlStyle.Width = Unit.Percentage (100);
1864                                 this.ControlStyle.Height = Unit.Percentage (100);
1865                                 this.CellPadding = 0;
1866                                 this.CellSpacing = 0;
1867
1868                                 this.Rows.Add (row);
1869                         }
1870
1871                         public virtual void PrepareControlHierarchy ()
1872                         {
1873                         }
1874                 }
1875
1876                 internal class BaseWizardNavigationContainer : Control, INamingContainer, INonBindingContainer
1877                 {
1878                         internal BaseWizardNavigationContainer ()
1879                         {
1880                         }
1881
1882                         public virtual void PrepareControlHierarchy ()
1883                         {
1884                         }
1885                 }
1886
1887                 internal abstract class DefaultContentContainer : BaseWizardContainer
1888                 {
1889                         bool _isDefault;
1890                         Wizard _wizard;
1891
1892                         protected bool IsDefaultTemplate {
1893                                 get { return _isDefault; }
1894                         }
1895
1896                         protected Wizard Wizard {
1897                                 get { return _wizard; }
1898                         }
1899
1900                         protected DefaultContentContainer (Wizard wizard)
1901                         {
1902                                 _wizard = wizard;
1903                         }
1904
1905                         public override sealed void PrepareControlHierarchy ()
1906                         {
1907                                 if (_isDefault)
1908                                         UpdateState ();
1909                         }
1910
1911                         protected abstract void UpdateState ();
1912
1913                         public void ConfirmDefaultTemplate ()
1914                         {
1915                                 _isDefault = true;
1916                         }
1917                 }
1918         }
1919 }
1920
1921 #endif