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