Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Web / UI / WebControls / Wizard.cs
blob882c5adcec85b0352e395b2e812f544b0c60d631
1 //------------------------------------------------------------------------------
2 // <copyright file="Wizard.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
7 namespace System.Web.UI.WebControls {
8 using System;
9 using System.Collections;
10 using System.Collections.Generic;
11 using System.ComponentModel;
12 using System.Diagnostics.CodeAnalysis;
13 using System.Drawing.Design;
14 using System.Globalization;
15 using System.Linq;
16 using System.Security.Permissions;
17 using System.Web;
18 using System.Web.UI;
19 using System.Web.Util;
22 Bindable(false),
23 DefaultEvent("FinishButtonClick"),
24 Designer("System.Web.UI.Design.WebControls.WizardDesigner, " + AssemblyRef.SystemDesign),
25 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>")
28 public class Wizard : CompositeControl {
30 private ITemplate _finishNavigationTemplate;
31 private ITemplate _headerTemplate;
32 private ITemplate _layoutTemplate;
33 private ITemplate _startNavigationTemplate;
34 private ITemplate _stepNavigationTemplate;
35 private ITemplate _sideBarTemplate;
37 private MultiView _multiView;
39 private static readonly object _eventActiveStepChanged = new object();
40 private static readonly object _eventFinishButtonClick = new object();
41 private static readonly object _eventNextButtonClick = new object();
42 private static readonly object _eventPreviousButtonClick = new object();
43 private static readonly object _eventSideBarButtonClick = new object();
44 private static readonly object _eventCancelButtonClick = new object();
46 //
47 public static readonly string HeaderPlaceholderId = "headerPlaceholder";
48 public static readonly string NavigationPlaceholderId = "navigationPlaceholder";
49 [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SideBar", Justification = "The casing has already been established in the context of Wizard")]
50 public static readonly string SideBarPlaceholderId = "sideBarPlaceholder";
51 public static readonly string WizardStepPlaceholderId = "wizardStepPlaceholder";
53 public static readonly string CancelCommandName = "Cancel";
54 public static readonly string MoveNextCommandName = "MoveNext";
55 public static readonly string MovePreviousCommandName = "MovePrevious";
56 public static readonly string MoveToCommandName = "Move";
57 public static readonly string MoveCompleteCommandName = "MoveComplete";
59 protected static readonly string CancelButtonID = "CancelButton";
60 protected static readonly string StartNextButtonID = "StartNextButton";
61 protected static readonly string StepPreviousButtonID = "StepPreviousButton";
62 protected static readonly string StepNextButtonID = "StepNextButton";
63 protected static readonly string FinishButtonID = "FinishButton";
64 protected static readonly string FinishPreviousButtonID = "FinishPreviousButton";
65 protected static readonly string CustomPreviousButtonID = "CustomPreviousButton";
66 protected static readonly string CustomNextButtonID = "CustomNextButton";
67 protected static readonly string CustomFinishButtonID = "CustomFinishButton";
68 protected static readonly string DataListID = "SideBarList";
69 protected static readonly string SideBarButtonID = "SideBarButton";
71 internal const string _customNavigationControls = "CustomNavigationControls";
73 private const string _templatedStepsID = "TemplatedWizardSteps";
74 private const string _multiViewID = "WizardMultiView";
76 private const string _customNavigationContainerIdPrefix = "__CustomNav";
78 private TableCell _sideBarTableCell;
80 private IWizardSideBarListControl _sideBarList;
82 private IButtonControl _commandSender;
83 private Dictionary<WizardStepBase, BaseNavigationTemplateContainer> _customNavigationContainers;
84 private IDictionary _designModeState;
85 private Stack<int> _historyStack;
86 private List<TemplatedWizardStep> _templatedSteps;
87 private WizardStepCollection _wizardStepCollection;
89 private WizardRenderingBase _rendering;
91 private bool _activeStepIndexSet;
92 private bool _displaySideBarDefault;
93 private bool _displaySideBar;
94 private bool? _isMacIE;
95 private bool _renderSideBarDataList;
97 private Style _cancelButtonStyle;
98 private Style _finishCompleteButtonStyle;
99 private Style _finishPreviousButtonStyle;
100 private Style _navigationButtonStyle;
101 private Style _sideBarButtonStyle;
102 private Style _startNextButtonStyle;
103 private Style _stepNextButtonStyle;
104 private Style _stepPreviousButtonStyle;
106 private TableItemStyle _headerStyle;
107 private TableItemStyle _navigationStyle;
108 private TableItemStyle _sideBarStyle;
109 private TableItemStyle _stepStyle;
111 private const bool _displaySideBarDefaultValue = true; /* default to true */
112 private const int _viewStateArrayLength = 15;
114 public Wizard()
115 : this(_displaySideBarDefaultValue) {
119 internal Wizard(bool displaySideBarDefault) {
120 _displaySideBarDefault = displaySideBarDefault;
121 _displaySideBar = displaySideBarDefault;
124 #region Public Properties
127 Browsable(false),
128 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
129 WebSysDescription(SR.Wizard_ActiveStep)
131 public WizardStepBase ActiveStep {
132 get {
133 if (ActiveStepIndex < -1 || ActiveStepIndex >= WizardSteps.Count) {
134 throw new InvalidOperationException(SR.GetString(SR.Wizard_ActiveStepIndex_out_of_range));
137 return MultiView.GetActiveView() as WizardStepBase;
143 DefaultValue(-1),
144 Themeable(false),
145 WebCategory("Behavior"),
146 WebSysDescription(SR.Wizard_ActiveStepIndex),
148 public virtual int ActiveStepIndex {
149 get {
150 return MultiView.ActiveViewIndex;
152 set {
153 if (value < -1 ||
154 (value >= WizardSteps.Count && ControlState >= ControlState.FrameworkInitialized)) {
155 throw new ArgumentOutOfRangeException("value",
156 SR.GetString(SR.Wizard_ActiveStepIndex_out_of_range));
159 if (MultiView.ActiveViewIndex != value) {
160 MultiView.ActiveViewIndex = value;
161 _activeStepIndexSet = true;
163 // Need to rebind the DataList control if the active step is changed.
164 // This is necessary since custom sidebar template might have different
165 // itemtemplates defined.
166 if (_sideBarList != null && SideBarTemplate != null) {
167 _sideBarList.SelectedIndex = ActiveStepIndex;
168 _sideBarList.DataBind();
175 /// <devdoc>
176 /// Gets or sets the URL of an image to be displayed for the cancel button.
177 /// </devdoc>
179 DefaultValue(""),
180 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
181 WebCategory("Appearance"),
182 WebSysDescription(SR.Wizard_CancelButtonImageUrl),
183 UrlProperty(),
185 public virtual string CancelButtonImageUrl {
186 get {
187 object obj = ViewState["CancelButtonImageUrl"];
188 return (obj == null) ? String.Empty : (string)obj;
190 set {
191 ViewState["CancelButtonImageUrl"] = value;
196 /// <devdoc>
197 /// Gets the style of the cancel buttons.
198 /// </devdoc>
200 WebCategory("Styles"),
201 DefaultValue(null),
202 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
203 NotifyParentProperty(true),
204 PersistenceMode(PersistenceMode.InnerProperty),
205 WebSysDescription(SR.Wizard_CancelButtonStyle)
207 public Style CancelButtonStyle {
208 get {
209 if (_cancelButtonStyle == null) {
210 _cancelButtonStyle = new Style();
211 if (IsTrackingViewState) {
212 ((IStateManager)_cancelButtonStyle).TrackViewState();
215 return _cancelButtonStyle;
221 Localizable(true),
222 WebCategory("Appearance"),
223 WebSysDefaultValue(SR.Wizard_Default_CancelButtonText),
224 WebSysDescription(SR.Wizard_CancelButtonText)
226 public virtual String CancelButtonText {
227 get {
228 string s = ViewState["CancelButtonText"] as String;
229 return s == null ? SR.GetString(SR.Wizard_Default_CancelButtonText) : s;
231 set {
232 if (value != CancelButtonText) {
233 ViewState["CancelButtonText"] = value;
240 DefaultValue(ButtonType.Button),
241 WebCategory("Appearance"),
242 WebSysDescription(SR.Wizard_CancelButtonType)
244 public virtual ButtonType CancelButtonType {
245 get {
246 object obj = ViewState["CancelButtonType"];
247 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
249 set {
250 ValidateButtonType(value);
251 ViewState["CancelButtonType"] = value;
257 DefaultValue(""),
258 Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
259 Themeable(false),
260 WebCategory("Behavior"),
261 WebSysDescription(SR.Wizard_CancelDestinationPageUrl),
262 UrlProperty(),
264 public virtual String CancelDestinationPageUrl {
265 get {
266 string s = ViewState["CancelDestinationPageUrl"] as String;
267 return s == null ? String.Empty : s;
269 set {
270 ViewState["CancelDestinationPageUrl"] = value;
276 WebCategory("Layout"),
277 DefaultValue(0),
278 WebSysDescription(SR.Wizard_CellPadding)
280 public virtual int CellPadding {
281 get {
282 if (ControlStyleCreated == false) {
283 return 0;
285 return ((TableStyle)ControlStyle).CellPadding;
287 set {
288 ((TableStyle)ControlStyle).CellPadding = value;
294 WebCategory("Layout"),
295 DefaultValue(0),
296 WebSysDescription(SR.Wizard_CellSpacing)
298 public virtual int CellSpacing {
299 get {
300 if (ControlStyleCreated == false) {
301 return 0;
303 return ((TableStyle)ControlStyle).CellSpacing;
305 set {
306 ((TableStyle)ControlStyle).CellSpacing = value;
312 DefaultValue(false),
313 Themeable(false),
314 WebCategory("Behavior"),
315 WebSysDescription(SR.Wizard_DisplayCancelButton),
317 public virtual bool DisplayCancelButton {
318 get {
319 object o = ViewState["DisplayCancelButton"];
320 return o == null ? false : (bool)o;
322 set {
323 ViewState["DisplayCancelButton"] = value;
329 DefaultValue(true),
330 Themeable(false),
331 WebCategory("Behavior"),
332 WebSysDescription(SR.Wizard_DisplaySideBar),
334 public virtual bool DisplaySideBar {
335 get {
336 return _displaySideBar;
338 set {
339 if (value != _displaySideBar) {
340 _displaySideBar = value;
341 _sideBarTableCell = null;
342 RequiresControlsRecreation();
348 /// <devdoc>
349 /// Gets or sets the URL of an image to be displayed for the finish button.
350 /// </devdoc>
352 DefaultValue(""),
353 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
354 WebCategory("Appearance"),
355 WebSysDescription(SR.Wizard_FinishCompleteButtonImageUrl),
356 UrlProperty(),
358 public virtual string FinishCompleteButtonImageUrl {
359 get {
360 object obj = ViewState["FinishCompleteButtonImageUrl"];
361 return (obj == null) ? String.Empty : (string)obj;
363 set {
364 ViewState["FinishCompleteButtonImageUrl"] = value;
369 /// <devdoc>
370 /// Gets the style of the finishStep buttons.
371 /// </devdoc>
373 WebCategory("Styles"),
374 DefaultValue(null),
375 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
376 NotifyParentProperty(true),
377 PersistenceMode(PersistenceMode.InnerProperty),
378 WebSysDescription(SR.Wizard_FinishCompleteButtonStyle)
380 public Style FinishCompleteButtonStyle {
381 get {
382 if (_finishCompleteButtonStyle == null) {
383 _finishCompleteButtonStyle = new Style();
384 if (IsTrackingViewState) {
385 ((IStateManager)_finishCompleteButtonStyle).TrackViewState();
388 return _finishCompleteButtonStyle;
394 Localizable(true),
395 WebCategory("Appearance"),
396 WebSysDefaultValue(SR.Wizard_Default_FinishButtonText),
397 WebSysDescription(SR.Wizard_FinishCompleteButtonText)
399 public virtual String FinishCompleteButtonText {
400 get {
401 string s = ViewState["FinishCompleteButtonText"] as String;
402 return s == null ? SR.GetString(SR.Wizard_Default_FinishButtonText) : s;
404 set {
405 ViewState["FinishCompleteButtonText"] = value;
411 WebCategory("Appearance"),
412 DefaultValue(ButtonType.Button),
413 WebSysDescription(SR.Wizard_FinishCompleteButtonType)
415 public virtual ButtonType FinishCompleteButtonType {
416 get {
417 object obj = ViewState["FinishCompleteButtonType"];
418 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
420 set {
421 ValidateButtonType(value);
422 ViewState["FinishCompleteButtonType"] = value;
427 /// <devdoc>
428 /// Gets or sets the URL for the continue button.
429 /// </devdoc>
431 DefaultValue(""),
432 Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
433 Themeable(false),
434 WebCategory("Behavior"),
435 WebSysDescription(SR.Wizard_FinishDestinationPageUrl),
436 UrlProperty(),
438 public virtual string FinishDestinationPageUrl {
439 get {
440 object obj = ViewState["FinishDestinationPageUrl"];
441 return (obj == null) ? String.Empty : (string)obj;
443 set {
444 ViewState["FinishDestinationPageUrl"] = value;
449 /// <devdoc>
450 /// Gets or sets the URL of an image to be displayed for the finish step's previous button.
451 /// </devdoc>
453 DefaultValue(""),
454 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
455 WebCategory("Appearance"),
456 WebSysDescription(SR.Wizard_FinishPreviousButtonImageUrl),
457 UrlProperty(),
459 public virtual string FinishPreviousButtonImageUrl {
460 get {
461 object obj = ViewState["FinishPreviousButtonImageUrl"];
462 return (obj == null) ? String.Empty : (string)obj;
464 set {
465 ViewState["FinishPreviousButtonImageUrl"] = value;
470 /// <devdoc>
471 /// Gets the style of the navigation buttons.
472 /// </devdoc>
474 WebCategory("Styles"),
475 DefaultValue(null),
476 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
477 NotifyParentProperty(true),
478 PersistenceMode(PersistenceMode.InnerProperty),
479 WebSysDescription(SR.Wizard_FinishPreviousButtonStyle)
481 public Style FinishPreviousButtonStyle {
482 get {
483 if (_finishPreviousButtonStyle == null) {
484 _finishPreviousButtonStyle = new Style();
485 if (IsTrackingViewState) {
486 ((IStateManager)_finishPreviousButtonStyle).TrackViewState();
489 return _finishPreviousButtonStyle;
495 Localizable(true),
496 WebCategory("Appearance"),
497 WebSysDefaultValue(SR.Wizard_Default_StepPreviousButtonText),
498 WebSysDescription(SR.Wizard_FinishPreviousButtonText)
500 public virtual String FinishPreviousButtonText {
501 get {
502 string s = ViewState["FinishPreviousButtonText"] as String;
503 return s == null ? SR.GetString(SR.Wizard_Default_StepPreviousButtonText) : s;
505 set {
506 ViewState["FinishPreviousButtonText"] = value;
512 WebCategory("Appearance"),
513 DefaultValue(ButtonType.Button),
514 WebSysDescription(SR.Wizard_FinishPreviousButtonType)
516 public virtual ButtonType FinishPreviousButtonType {
517 get {
518 object obj = ViewState["FinishPreviousButtonType"];
519 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
521 set {
522 ValidateButtonType(value);
523 ViewState["FinishPreviousButtonType"] = value;
529 Browsable(false),
530 DefaultValue(null),
531 PersistenceMode(PersistenceMode.InnerProperty),
532 TemplateContainer(typeof(Wizard)),
533 WebSysDescription(SR.Wizard_FinishNavigationTemplate)
535 public virtual ITemplate FinishNavigationTemplate {
536 get {
537 return _finishNavigationTemplate;
539 set {
540 _finishNavigationTemplate = value;
541 RequiresControlsRecreation();
547 WebCategory("Styles"),
548 DefaultValue(null),
549 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
550 NotifyParentProperty(true),
551 PersistenceMode(PersistenceMode.InnerProperty),
552 WebSysDescription(SR.WebControl_HeaderStyle)
554 public TableItemStyle HeaderStyle {
555 get {
556 if (_headerStyle == null) {
557 _headerStyle = new TableItemStyle();
558 if (IsTrackingViewState)
559 ((IStateManager)_headerStyle).TrackViewState();
561 return _headerStyle;
567 Browsable(false),
568 DefaultValue(null),
569 PersistenceMode(PersistenceMode.InnerProperty),
570 TemplateContainer(typeof(Wizard)),
571 WebSysDescription(SR.WebControl_HeaderTemplate)
573 public virtual ITemplate HeaderTemplate {
574 get {
575 return _headerTemplate;
577 set {
578 _headerTemplate = value;
579 RequiresControlsRecreation();
585 DefaultValue(""),
586 Localizable(true),
587 WebCategory("Appearance"),
588 WebSysDescription(SR.Wizard_HeaderText)
590 public virtual string HeaderText {
591 get {
592 string s = ViewState["HeaderText"] as String;
593 return s == null ? String.Empty : s;
595 set {
596 ViewState["HeaderText"] = value;
602 Browsable(false),
603 DefaultValue(null),
604 PersistenceMode(PersistenceMode.InnerProperty),
605 TemplateContainer(typeof(Wizard)),
606 WebSysDescription(SR.Wizard_LayoutTemplate)
608 public virtual ITemplate LayoutTemplate {
609 get {
610 return _layoutTemplate;
612 set {
613 _layoutTemplate = value;
614 RequiresControlsRecreation();
619 /// <devdoc>
620 /// Gets the style of the navigation buttons.
621 /// </devdoc>
623 WebCategory("Styles"),
624 DefaultValue(null),
625 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
626 NotifyParentProperty(true),
627 PersistenceMode(PersistenceMode.InnerProperty),
628 WebSysDescription(SR.Wizard_NavigationButtonStyle)
630 public Style NavigationButtonStyle {
631 get {
632 if (_navigationButtonStyle == null) {
633 _navigationButtonStyle = new Style();
634 if (IsTrackingViewState) {
635 ((IStateManager)_navigationButtonStyle).TrackViewState();
638 return _navigationButtonStyle;
644 WebCategory("Styles"),
645 DefaultValue(null),
646 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
647 NotifyParentProperty(true),
648 PersistenceMode(PersistenceMode.InnerProperty),
649 WebSysDescription(SR.Wizard_NavigationStyle)
651 public TableItemStyle NavigationStyle {
652 get {
653 if (_navigationStyle == null) {
654 _navigationStyle = new TableItemStyle();
655 if (IsTrackingViewState)
656 ((IStateManager)_navigationStyle).TrackViewState();
658 return _navigationStyle;
663 /// <devdoc>
664 /// Gets or sets the URL of an image to be displayed for the finish step's previous button.
665 /// </devdoc>
667 DefaultValue(""),
668 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
669 WebCategory("Appearance"),
670 WebSysDescription(SR.Wizard_StartNextButtonImageUrl),
671 UrlProperty(),
673 public virtual string StartNextButtonImageUrl {
674 get {
675 object obj = ViewState["StartNextButtonImageUrl"];
676 return (obj == null) ? String.Empty : (string)obj;
678 set {
679 ViewState["StartNextButtonImageUrl"] = value;
684 /// <devdoc>
685 /// Gets the style of the navigation buttons.
686 /// </devdoc>
688 WebCategory("Styles"),
689 DefaultValue(null),
690 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
691 NotifyParentProperty(true),
692 PersistenceMode(PersistenceMode.InnerProperty),
693 WebSysDescription(SR.Wizard_StartNextButtonStyle)
695 public Style StartNextButtonStyle {
696 get {
697 if (_startNextButtonStyle == null) {
698 _startNextButtonStyle = new Style();
699 if (IsTrackingViewState) {
700 ((IStateManager)_startNextButtonStyle).TrackViewState();
703 return _startNextButtonStyle;
709 Localizable(true),
710 WebCategory("Appearance"),
711 WebSysDefaultValue(SR.Wizard_Default_StepNextButtonText),
712 WebSysDescription(SR.Wizard_StartNextButtonText)
714 public virtual String StartNextButtonText {
715 get {
716 string s = ViewState["StartNextButtonText"] as String;
717 return s == null ? SR.GetString(SR.Wizard_Default_StepNextButtonText) : s;
719 set {
720 ViewState["StartNextButtonText"] = value;
726 WebCategory("Appearance"),
727 DefaultValue(ButtonType.Button),
728 WebSysDescription(SR.Wizard_StartNextButtonType)
730 public virtual ButtonType StartNextButtonType {
731 get {
732 object obj = ViewState["StartNextButtonType"];
733 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
735 set {
736 ValidateButtonType(value);
737 ViewState["StartNextButtonType"] = value;
742 /// <devdoc>
743 /// Gets or sets the URL of an image to be displayed for the next button.
744 /// </devdoc>
746 DefaultValue(""),
747 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
748 WebCategory("Appearance"),
749 WebSysDescription(SR.Wizard_StepNextButtonImageUrl),
750 UrlProperty(),
752 public virtual string StepNextButtonImageUrl {
753 get {
754 object obj = ViewState["StepNextButtonImageUrl"];
755 return (obj == null) ? String.Empty : (string)obj;
757 set {
758 ViewState["StepNextButtonImageUrl"] = value;
763 /// <devdoc>
764 /// Gets the style of the navigation buttons.
765 /// </devdoc>
767 WebCategory("Styles"),
768 DefaultValue(null),
769 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
770 NotifyParentProperty(true),
771 PersistenceMode(PersistenceMode.InnerProperty),
772 WebSysDescription(SR.Wizard_StepNextButtonStyle)
774 public Style StepNextButtonStyle {
775 get {
776 if (_stepNextButtonStyle == null) {
777 _stepNextButtonStyle = new Style();
778 if (IsTrackingViewState) {
779 ((IStateManager)_stepNextButtonStyle).TrackViewState();
782 return _stepNextButtonStyle;
788 Localizable(true),
789 WebCategory("Appearance"),
790 WebSysDefaultValue(SR.Wizard_Default_StepNextButtonText),
791 WebSysDescription(SR.Wizard_StepNextButtonText)
793 public virtual String StepNextButtonText {
794 get {
795 string s = ViewState["StepNextButtonText"] as String;
796 return s == null ? SR.GetString(SR.Wizard_Default_StepNextButtonText) : s;
798 set {
799 ViewState["StepNextButtonText"] = value;
805 WebCategory("Appearance"),
806 DefaultValue(ButtonType.Button),
807 WebSysDescription(SR.Wizard_StepNextButtonType)
809 public virtual ButtonType StepNextButtonType {
810 get {
811 object obj = ViewState["StepNextButtonType"];
812 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
814 set {
815 ValidateButtonType(value);
816 ViewState["StepNextButtonType"] = value;
821 /// <devdoc>
822 /// Gets or sets the URL of an image to be displayed for the previous button.
823 /// </devdoc>
825 DefaultValue(""),
826 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
827 WebCategory("Appearance"),
828 WebSysDescription(SR.Wizard_StepPreviousButtonImageUrl),
829 UrlProperty(),
831 public virtual string StepPreviousButtonImageUrl {
832 get {
833 object obj = ViewState["StepPreviousButtonImageUrl"];
834 return (obj == null) ? String.Empty : (string)obj;
836 set {
837 ViewState["StepPreviousButtonImageUrl"] = value;
842 /// <devdoc>
843 /// Gets the style of the navigation buttons.
844 /// </devdoc>
846 WebCategory("Styles"),
847 DefaultValue(null),
848 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
849 NotifyParentProperty(true),
850 PersistenceMode(PersistenceMode.InnerProperty),
851 WebSysDescription(SR.Wizard_StepPreviousButtonStyle)
853 public Style StepPreviousButtonStyle {
854 get {
855 if (_stepPreviousButtonStyle == null) {
856 _stepPreviousButtonStyle = new Style();
857 if (IsTrackingViewState) {
858 ((IStateManager)_stepPreviousButtonStyle).TrackViewState();
861 return _stepPreviousButtonStyle;
867 Localizable(true),
868 WebCategory("Appearance"),
869 WebSysDefaultValue(SR.Wizard_Default_StepPreviousButtonText),
870 WebSysDescription(SR.Wizard_StepPreviousButtonText)
872 public virtual String StepPreviousButtonText {
873 get {
874 string s = ViewState["StepPreviousButtonText"] as String;
875 return s == null ? SR.GetString(SR.Wizard_Default_StepPreviousButtonText) : s;
877 set {
878 ViewState["StepPreviousButtonText"] = value;
884 WebCategory("Appearance"),
885 DefaultValue(ButtonType.Button),
886 WebSysDescription(SR.Wizard_StepPreviousButtonType)
888 public virtual ButtonType StepPreviousButtonType {
889 get {
890 object obj = ViewState["StepPreviousButtonType"];
891 return (obj == null) ? ButtonType.Button : (ButtonType)obj;
893 set {
894 ValidateButtonType(value);
895 ViewState["StepPreviousButtonType"] = value;
900 /// <devdoc>
901 /// Gets the style of the side bar buttons.
902 /// </devdoc>
904 WebCategory("Styles"),
905 DefaultValue(null),
906 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
907 NotifyParentProperty(true),
908 PersistenceMode(PersistenceMode.InnerProperty),
909 WebSysDescription(SR.Wizard_SideBarButtonStyle)
911 public Style SideBarButtonStyle {
912 get {
913 if (_sideBarButtonStyle == null) {
914 _sideBarButtonStyle = new Style();
915 if (IsTrackingViewState) {
916 ((IStateManager)_sideBarButtonStyle).TrackViewState();
919 return _sideBarButtonStyle;
925 WebCategory("Styles"),
926 DefaultValue(null),
927 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
928 NotifyParentProperty(true),
929 PersistenceMode(PersistenceMode.InnerProperty),
930 WebSysDescription(SR.Wizard_SideBarStyle)
932 public TableItemStyle SideBarStyle {
933 get {
934 if (_sideBarStyle == null) {
935 _sideBarStyle = new TableItemStyle();
936 if (IsTrackingViewState)
937 ((IStateManager)_sideBarStyle).TrackViewState();
939 return _sideBarStyle;
945 Browsable(false),
946 DefaultValue(null),
947 PersistenceMode(PersistenceMode.InnerProperty),
948 TemplateContainer(typeof(Wizard)),
949 WebSysDescription(SR.Wizard_SideBarTemplate)
951 public virtual ITemplate SideBarTemplate {
952 get {
953 return _sideBarTemplate;
955 set {
956 _sideBarTemplate = value;
957 _sideBarTableCell = null;
958 RequiresControlsRecreation();
964 Localizable(true),
965 WebCategory("Appearance"),
966 WebSysDefaultValue(SR.Wizard_Default_SkipToContentText),
967 WebSysDescription(SR.WebControl_SkipLinkText)
969 public virtual String SkipLinkText {
970 get {
971 string s = SkipLinkTextInternal;
972 return s == null ? SR.GetString(SR.Wizard_Default_SkipToContentText) : s;
974 set {
975 ViewState["SkipLinkText"] = value;
981 Browsable(false),
982 DefaultValue(null),
983 PersistenceMode(PersistenceMode.InnerProperty),
984 TemplateContainer(typeof(Wizard)),
985 WebSysDescription(SR.Wizard_StartNavigationTemplate)
987 public virtual ITemplate StartNavigationTemplate {
988 get {
989 return _startNavigationTemplate;
991 set {
992 _startNavigationTemplate = value;
993 RequiresControlsRecreation();
999 Browsable(false),
1000 DefaultValue(null),
1001 PersistenceMode(PersistenceMode.InnerProperty),
1002 TemplateContainer(typeof(Wizard)),
1003 WebSysDescription(SR.Wizard_StepNavigationTemplate)
1005 public virtual ITemplate StepNavigationTemplate {
1006 get {
1007 return _stepNavigationTemplate;
1009 set {
1010 _stepNavigationTemplate = value;
1011 RequiresControlsRecreation();
1017 DefaultValue(null),
1018 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1019 NotifyParentProperty(true),
1020 PersistenceMode(PersistenceMode.InnerProperty),
1021 WebCategory("Styles"),
1022 WebSysDescription(SR.Wizard_StepStyle)
1024 public TableItemStyle StepStyle {
1025 get {
1026 if (_stepStyle == null) {
1027 _stepStyle = new TableItemStyle();
1028 if (IsTrackingViewState)
1029 ((IStateManager)_stepStyle).TrackViewState();
1031 return _stepStyle;
1037 protected override HtmlTextWriterTag TagKey {
1038 get {
1039 return HtmlTextWriterTag.Table;
1045 DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1046 Editor("System.Web.UI.Design.WebControls.WizardStepCollectionEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
1047 PersistenceMode(PersistenceMode.InnerProperty),
1048 Themeable(false),
1049 WebSysDescription(SR.Wizard_WizardSteps),
1051 public virtual WizardStepCollection WizardSteps {
1052 get {
1053 if (_wizardStepCollection == null) {
1054 _wizardStepCollection = new WizardStepCollection(this);
1057 return _wizardStepCollection;
1061 #endregion
1063 #region Public Events
1066 WebCategory("Action"),
1067 WebSysDescription(SR.Wizard_ActiveStepChanged)
1069 public event EventHandler ActiveStepChanged {
1070 add {
1071 Events.AddHandler(_eventActiveStepChanged, value);
1073 remove {
1074 Events.RemoveHandler(_eventActiveStepChanged, value);
1080 WebCategory("Action"),
1081 WebSysDescription(SR.Wizard_CancelButtonClick)
1083 public event EventHandler CancelButtonClick {
1084 add {
1085 Events.AddHandler(_eventCancelButtonClick, value);
1087 remove {
1089 Events.RemoveHandler(_eventCancelButtonClick, value);
1095 WebCategory("Action"),
1096 WebSysDescription(SR.Wizard_FinishButtonClick)
1098 public event WizardNavigationEventHandler FinishButtonClick {
1099 add {
1100 Events.AddHandler(_eventFinishButtonClick, value);
1102 remove {
1103 Events.RemoveHandler(_eventFinishButtonClick, value);
1109 WebCategory("Action"),
1110 WebSysDescription(SR.Wizard_NextButtonClick)
1112 public event WizardNavigationEventHandler NextButtonClick {
1113 add {
1114 Events.AddHandler(_eventNextButtonClick, value);
1116 remove {
1118 Events.RemoveHandler(_eventNextButtonClick, value);
1124 WebCategory("Action"),
1125 WebSysDescription(SR.Wizard_PreviousButtonClick)
1127 public event WizardNavigationEventHandler PreviousButtonClick {
1128 add {
1129 Events.AddHandler(_eventPreviousButtonClick, value);
1131 remove {
1132 Events.RemoveHandler(_eventPreviousButtonClick, value);
1138 WebCategory("Action"),
1139 WebSysDescription(SR.Wizard_SideBarButtonClick)
1141 public virtual event WizardNavigationEventHandler SideBarButtonClick {
1142 add {
1143 Events.AddHandler(_eventSideBarButtonClick, value);
1145 remove {
1146 Events.RemoveHandler(_eventSideBarButtonClick, value);
1150 #endregion
1152 #region Internal Properties
1154 internal Dictionary<WizardStepBase, BaseNavigationTemplateContainer> CustomNavigationContainers {
1155 get {
1156 if (_customNavigationContainers == null) {
1157 _customNavigationContainers = new Dictionary<WizardStepBase, BaseNavigationTemplateContainer>();
1159 return _customNavigationContainers;
1164 private ITemplate CustomNavigationTemplate {
1165 get {
1166 var templatedActiveStep = ActiveStep as TemplatedWizardStep;
1167 return templatedActiveStep == null ? null : templatedActiveStep.CustomNavigationTemplate;
1172 private Stack<int> History {
1173 get {
1174 if (_historyStack == null)
1175 _historyStack = new Stack<int>();
1177 return _historyStack;
1181 private bool IsMacIE5 {
1182 get {
1183 if (!_isMacIE.HasValue && !DesignMode) {
1184 HttpBrowserCapabilities browser = null;
1185 if (Page != null) {
1186 browser = Page.Request.Browser;
1187 } else {
1188 HttpContext context = HttpContext.Current;
1189 // Context could be null if this control is created by the parser at designtime
1190 if (context != null) {
1191 browser = context.Request.Browser;
1195 _isMacIE = (browser != null && browser.Type == "IE5" && browser.Platform == "MacPPC");
1198 return _isMacIE.Value;
1203 internal MultiView MultiView {
1204 get {
1205 if (_multiView == null) {
1206 _multiView = new MultiView();
1207 _multiView.EnableTheming = true;
1208 _multiView.ID = _multiViewID;
1209 _multiView.ActiveViewChanged += new EventHandler(this.MultiViewActiveViewChanged);
1210 _multiView.IgnoreBubbleEvents();
1213 return _multiView;
1218 internal virtual bool ShowCustomNavigationTemplate {
1219 get {
1220 return CustomNavigationTemplate != null;
1225 internal bool ShouldRenderChildControl {
1226 get {
1227 if (!DesignMode) {
1228 return true;
1231 if (_designModeState == null) {
1232 return true;
1235 object o = _designModeState["ShouldRenderWizardSteps"];
1236 return o == null ? true : (bool)o;
1241 private IWizardSideBarListControl SideBarList {
1242 get { return _sideBarList; }
1246 private bool SideBarEnabled {
1247 get {
1248 return _sideBarList != null && DisplaySideBar;
1253 internal string SkipLinkTextInternal {
1254 get {
1255 return ViewState["SkipLinkText"] as String;
1260 internal List<TemplatedWizardStep> TemplatedSteps {
1261 get {
1262 if (_templatedSteps == null) {
1263 _templatedSteps = new List<TemplatedWizardStep>();
1265 return _templatedSteps;
1269 #endregion
1271 private void MultiViewActiveViewChanged(object source, EventArgs e) {
1272 OnActiveStepChanged(this, EventArgs.Empty);
1276 private void ApplyControlProperties() {
1277 _rendering.ApplyControlProperties();
1281 internal BaseNavigationTemplateContainer CreateBaseNavigationTemplateContainer(string id) {
1282 return new BaseNavigationTemplateContainer(this) {
1283 ID = id
1288 /// <internalonly />
1289 protected internal override void CreateChildControls() {
1290 using (new WizardControlCollectionModifier(this)) {
1291 Controls.Clear();
1292 _customNavigationContainers = null;
1295 if (LayoutTemplate == null) {
1296 _rendering = CreateTableRendering();
1298 else {
1299 _rendering = CreateLayoutTemplateRendering();
1302 CreateControlHierarchy();
1303 ClearChildViewState();
1306 internal virtual TableWizardRendering CreateTableRendering() {
1307 return new TableWizardRendering(this);
1310 internal virtual LayoutTemplateWizardRendering CreateLayoutTemplateRendering() {
1311 return new LayoutTemplateWizardRendering(this);
1315 protected override ControlCollection CreateControlCollection() {
1316 return new WizardControlCollection(this);
1320 protected virtual void CreateControlHierarchy() {
1321 _rendering.CreateControlHierarchy();
1325 private void SetStepsAndDataBindSideBarList(IWizardSideBarListControl sideBarList) {
1326 if (sideBarList != null) {
1327 sideBarList.DataSource = WizardSteps;
1328 sideBarList.SelectedIndex = ActiveStepIndex;
1329 sideBarList.DataBind();
1334 internal virtual ITemplate CreateDefaultSideBarTemplate() {
1335 return new DefaultSideBarTemplate(this);
1338 internal virtual ITemplate CreateDefaultDataListItemTemplate() {
1339 return new DataListItemTemplate(this);
1343 /// <internalonly/>
1344 /// <devdoc>
1345 /// <para>A protected method. Creates a table control style.</para>
1346 /// </devdoc>
1347 protected override Style CreateControlStyle() {
1348 TableStyle controlStyle = new TableStyle();
1350 // initialize defaults that are different from TableStyle
1351 controlStyle.CellSpacing = 0;
1352 controlStyle.CellPadding = 0;
1354 return controlStyle;
1357 internal virtual void CreateCustomNavigationTemplates() {
1358 for (int i = 0; i < WizardSteps.Count; ++i) {
1359 TemplatedWizardStep step = WizardSteps[i] as TemplatedWizardStep;
1360 if (step != null) {
1361 RegisterCustomNavigationContainers(step);
1366 internal void RegisterCustomNavigationContainers(TemplatedWizardStep step) {
1367 // Instantiate the step's ContentTemplate
1368 InstantiateStepContentTemplate(step);
1370 if (!CustomNavigationContainers.ContainsKey(step)) {
1371 BaseNavigationTemplateContainer container = null;
1372 string id = GetCustomContainerID(WizardSteps.IndexOf(step));
1373 if (step.CustomNavigationTemplate != null) {
1374 container = CreateBaseNavigationTemplateContainer(id);
1375 step.CustomNavigationTemplate.InstantiateIn(container);
1376 step.CustomNavigationTemplateContainer = container;
1377 container.RegisterButtonCommandEvents();
1378 } else {
1379 container = CreateBaseNavigationTemplateContainer(id);
1380 container.RegisterButtonCommandEvents();
1382 CustomNavigationContainers[step] = container;
1387 internal virtual void DataListItemDataBound(object sender, WizardSideBarListControlItemEventArgs e) {
1388 var dataListItem = e.Item;
1390 // Ignore the item that is not created from DataSource
1391 if (dataListItem.ItemType != ListItemType.Item &&
1392 dataListItem.ItemType != ListItemType.AlternatingItem &&
1393 dataListItem.ItemType != ListItemType.SelectedItem &&
1394 dataListItem.ItemType != ListItemType.EditItem) {
1395 return;
1398 IButtonControl button = dataListItem.FindControl(SideBarButtonID) as IButtonControl;
1399 if (button == null) {
1400 if (!DesignMode) {
1401 throw new InvalidOperationException(
1402 SR.GetString(SR.Wizard_SideBar_Button_Not_Found, DataListID, SideBarButtonID));
1405 return;
1408 var ctrlButton = button as Button;
1409 if (ctrlButton != null) {
1410 // Use javascript submit to use the postdata instead, this is necessarily since the buttons could be recreated during DataBind(). Previously
1411 // registered buttons will lose their parents and events won't bubble up. VSWhidbey 120640.
1412 // For devices that do not support Javascript, fall back to sumit behavior VSWhidbey 154576
1413 ctrlButton.UseSubmitBehavior = false;
1416 WebControl webCtrlButton = button as WebControl;
1417 if (webCtrlButton != null) {
1418 webCtrlButton.TabIndex = this.TabIndex;
1421 int index = 0;
1423 // Render wizardstep title on the button control.
1424 WizardStepBase step = dataListItem.DataItem as WizardStepBase;
1425 if (step != null) {
1426 // Disable the button if it's a Complete step.
1427 if (GetStepType(step) == WizardStepType.Complete &&
1428 webCtrlButton != null) {
1429 webCtrlButton.Enabled = false;
1432 // Need to render the sidebar tablecell.
1433 RegisterSideBarDataListForRender();
1435 // Use the step title if defined, otherwise use ID
1436 if (step.Title.Length > 0) {
1437 button.Text = step.Title;
1438 } else {
1439 button.Text = step.ID;
1442 index = WizardSteps.IndexOf(step);
1444 button.CommandName = MoveToCommandName;
1445 button.CommandArgument = index.ToString(NumberFormatInfo.InvariantInfo);
1447 RegisterCommandEvents(button);
1451 internal void RegisterSideBarDataListForRender() {
1452 _renderSideBarDataList = true;
1455 private void DataListItemCommand(object sender, CommandEventArgs e) {
1456 if (!MoveToCommandName.Equals(e.CommandName, StringComparison.OrdinalIgnoreCase)) {
1457 return;
1460 int oldIndex = ActiveStepIndex;
1461 int newIndex = Int32.Parse((String)e.CommandArgument, CultureInfo.InvariantCulture);
1463 WizardNavigationEventArgs args = new WizardNavigationEventArgs(oldIndex, newIndex);
1465 // Never cancel the item command at design time.
1466 if (_commandSender != null && !DesignMode && Page != null && !Page.IsValid) {
1467 args.Cancel = true;
1470 _activeStepIndexSet = false;
1471 OnSideBarButtonClick(args);
1473 if (!args.Cancel) {
1474 // Honor user's change if activeStepIndex is set explicitely;
1475 if (!_activeStepIndexSet) {
1476 if (AllowNavigationToStep(newIndex)) {
1477 ActiveStepIndex = newIndex;
1480 } else {
1481 // revert active step if it's cancelled.
1482 ActiveStepIndex = oldIndex;
1486 internal static string GetCustomContainerID(int index) {
1487 return _customNavigationContainerIdPrefix + index;
1491 /// <internalonly/>
1492 [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
1493 protected override IDictionary GetDesignModeState() {
1494 IDictionary dictionary = base.GetDesignModeState();
1495 Debug.Assert(dictionary != null && DesignMode);
1497 _designModeState = dictionary;
1498 int oldIndex = ActiveStepIndex;
1500 // Set the activestepindex to 0 in designmode if it's -1.
1501 try {
1502 if (oldIndex == -1 && WizardSteps.Count > 0) {
1503 ActiveStepIndex = 0;
1506 RequiresControlsRecreation();
1507 EnsureChildControls();
1508 ApplyControlProperties();
1510 _rendering.SetDesignModeState(dictionary);
1512 if (ShowCustomNavigationTemplate) {
1513 BaseNavigationTemplateContainer customContainer = CustomNavigationContainers[ActiveStep];
1514 dictionary[CustomNextButtonID] = customContainer.NextButton;
1515 dictionary[CustomPreviousButtonID] = customContainer.PreviousButton;
1516 dictionary[CustomFinishButtonID] = customContainer.FinishButton;
1517 dictionary[CancelButtonID] = customContainer.CancelButton;
1518 dictionary[_customNavigationControls] = customContainer.Controls;
1521 // VSWhidbey 456506. Reset the ItemTemplate so it can be persisted correctly
1522 // based on current SideBarButtonStyle
1523 if (SideBarTemplate == null && _sideBarList != null) {
1524 _sideBarList.ItemTemplate = CreateDefaultDataListItemTemplate();
1527 dictionary[DataListID] = _sideBarList;
1528 dictionary[_templatedStepsID] = TemplatedSteps;
1529 } finally {
1530 ActiveStepIndex = oldIndex;
1533 return dictionary;
1537 public ICollection GetHistory() {
1538 ArrayList list = new ArrayList();
1539 foreach (int index in History) {
1540 list.Add(WizardSteps[index]);
1542 return list;
1545 internal int GetPreviousStepIndex(bool popStack) {
1546 int previousIndex = -1;
1547 int index = ActiveStepIndex;
1549 if (_historyStack == null || _historyStack.Count == 0) {
1550 return previousIndex;
1553 if (popStack) {
1554 previousIndex = _historyStack.Pop();
1556 // Ignore the current step, the current step index is already in the historyStack.
1557 if (previousIndex == index && _historyStack.Count > 0) {
1558 previousIndex = _historyStack.Pop();
1560 } else {
1561 previousIndex = _historyStack.Peek();
1563 // Ignore the current step, the current step index is already in the historyStack.
1564 if (previousIndex == index && _historyStack.Count > 1) {
1565 int originalIndex = _historyStack.Pop();
1566 previousIndex = _historyStack.Peek();
1567 _historyStack.Push(originalIndex);
1571 // Return -1 if the current step is same as previous step
1572 if (previousIndex == index) {
1573 return -1;
1576 return previousIndex;
1579 private WizardStepType GetStepType(int index) {
1580 Debug.Assert(index > -1 && index < WizardSteps.Count);
1581 WizardStepBase step = WizardSteps[index] as WizardStepBase;
1582 return GetStepType(step, index);
1585 private WizardStepType GetStepType(WizardStepBase step) {
1586 int index = WizardSteps.IndexOf(step);
1587 return GetStepType(step, index);
1591 public WizardStepType GetStepType(WizardStepBase wizardStep, int index) {
1592 if (wizardStep.StepType == WizardStepType.Auto) {
1594 // If it's the only step or a Complete step is after current step, then make it Finish step
1595 if (WizardSteps.Count == 1 ||
1596 (index < WizardSteps.Count - 1 &&
1597 WizardSteps[index + 1].StepType == WizardStepType.Complete)) {
1598 return WizardStepType.Finish;
1601 // First one is the start step
1602 if (index == 0) {
1603 return WizardStepType.Start;
1606 // Last one is the finish step
1607 if (index == WizardSteps.Count - 1) {
1608 return WizardStepType.Finish;
1611 return WizardStepType.Step;
1614 return wizardStep.StepType;
1617 /// <devdoc>
1618 /// Instantiates all the content templates for each TemplatedWizardStep
1619 /// </devdoc>
1620 internal virtual void InstantiateStepContentTemplates() {
1621 TemplatedSteps.ForEach(step => InstantiateStepContentTemplate(step));
1624 internal void InstantiateStepContentTemplate(TemplatedWizardStep step) {
1625 step.Controls.Clear();
1627 BaseContentTemplateContainer container = new BaseContentTemplateContainer(this, true);
1628 ITemplate contentTemplate = step.ContentTemplate;
1630 if (contentTemplate != null) {
1631 container.SetEnableTheming();
1632 contentTemplate.InstantiateIn(container.InnerCell);
1635 step.ContentTemplateContainer = container;
1636 step.Controls.Add(container);
1639 /// <devdoc>
1640 /// <para>Loads the control state.</para>
1641 /// </devdoc>
1642 protected internal override void LoadControlState(object state) {
1643 Triplet t = state as Triplet;
1644 if (t != null) {
1645 base.LoadControlState(t.First);
1647 Array collection = t.Second as Array;
1648 if (collection != null) {
1649 Array.Reverse(collection);
1650 _historyStack = new Stack<int>(collection.Cast<int>());
1653 ActiveStepIndex = (int)t.Third;
1658 protected override void LoadViewState(object savedState) {
1659 if (savedState == null) {
1660 base.LoadViewState(null);
1661 } else {
1662 object[] myState = (object[])savedState;
1663 if (myState.Length != _viewStateArrayLength) {
1664 throw new ArgumentException(SR.GetString(SR.ViewState_InvalidViewState));
1667 base.LoadViewState(myState[0]);
1669 if (myState[1] != null)
1670 ((IStateManager)NavigationButtonStyle).LoadViewState(myState[1]);
1672 if (myState[2] != null)
1673 ((IStateManager)SideBarButtonStyle).LoadViewState(myState[2]);
1675 if (myState[3] != null)
1676 ((IStateManager)HeaderStyle).LoadViewState(myState[3]);
1678 if (myState[4] != null)
1679 ((IStateManager)NavigationStyle).LoadViewState(myState[4]);
1681 if (myState[5] != null)
1682 ((IStateManager)SideBarStyle).LoadViewState(myState[5]);
1684 if (myState[6] != null)
1685 ((IStateManager)StepStyle).LoadViewState(myState[6]);
1687 if (myState[7] != null)
1688 ((IStateManager)StartNextButtonStyle).LoadViewState(myState[7]);
1690 if (myState[8] != null)
1691 ((IStateManager)StepNextButtonStyle).LoadViewState(myState[8]);
1693 if (myState[9] != null)
1694 ((IStateManager)StepPreviousButtonStyle).LoadViewState(myState[9]);
1696 if (myState[10] != null)
1697 ((IStateManager)FinishPreviousButtonStyle).LoadViewState(myState[10]);
1699 if (myState[11] != null)
1700 ((IStateManager)FinishCompleteButtonStyle).LoadViewState(myState[11]);
1702 if (myState[12] != null)
1703 ((IStateManager)CancelButtonStyle).LoadViewState(myState[12]);
1705 if (myState[13] != null)
1706 ((IStateManager)ControlStyle).LoadViewState(myState[13]);
1708 if (myState[14] != null)
1709 DisplaySideBar = (bool)myState[14];
1714 public void MoveTo(WizardStepBase wizardStep) {
1715 if (wizardStep == null)
1716 throw new ArgumentNullException("wizardStep");
1718 int index = WizardSteps.IndexOf(wizardStep);
1719 if (index == -1) {
1720 throw new ArgumentException(SR.GetString(SR.Wizard_Step_Not_In_Wizard));
1723 ActiveStepIndex = index;
1727 protected virtual void OnActiveStepChanged(object source, EventArgs e) {
1728 EventHandler handler = (EventHandler)Events[_eventActiveStepChanged];
1729 if (handler != null) handler(this, e);
1733 protected override bool OnBubbleEvent(object source, EventArgs e) {
1734 bool handled = false;
1736 CommandEventArgs ce = e as CommandEventArgs;
1737 if (ce != null) {
1738 if (String.Equals(CancelCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
1739 OnCancelButtonClick(EventArgs.Empty);
1740 return true;
1743 int oldIndex = ActiveStepIndex;
1744 int newIndex = oldIndex;
1746 // Check if we need to validate the bubble commands VSWhidbey 312445
1747 bool verifyEvent = true;
1749 WizardStepType stepType = WizardStepType.Auto;
1750 WizardStepBase step = WizardSteps[oldIndex];
1752 // Don't validate commands if it's a templated wizard step
1753 if (step is TemplatedWizardStep) {
1754 verifyEvent = false;
1755 } else {
1756 stepType = GetStepType(step);
1759 WizardNavigationEventArgs args = new WizardNavigationEventArgs(oldIndex, newIndex);
1761 // Do not navigate away from current view if view is not valid.
1762 if (_commandSender != null && Page != null && !Page.IsValid) {
1763 args.Cancel = true;
1766 bool previousButtonCommand = false;
1767 _activeStepIndexSet = false;
1769 if (String.Equals(MoveNextCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
1770 if (verifyEvent) {
1771 if (stepType != WizardStepType.Start && stepType != WizardStepType.Step) {
1772 throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MoveNextCommandName));
1776 if (oldIndex < WizardSteps.Count - 1) {
1777 args.SetNextStepIndex(oldIndex + 1);
1780 OnNextButtonClick(args);
1781 handled = true;
1782 } else if (String.Equals(MovePreviousCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
1783 if (verifyEvent) {
1784 if (stepType != WizardStepType.Step && stepType != WizardStepType.Finish) {
1785 throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MovePreviousCommandName));
1789 previousButtonCommand = true;
1791 int previousIndex = GetPreviousStepIndex(false);
1792 if (previousIndex != -1) {
1793 args.SetNextStepIndex(previousIndex);
1796 OnPreviousButtonClick(args);
1797 handled = true;
1798 } else if (String.Equals(MoveCompleteCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
1799 if (verifyEvent) {
1800 if (stepType != WizardStepType.Finish) {
1801 throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MoveCompleteCommandName));
1805 if (oldIndex < WizardSteps.Count - 1) {
1806 args.SetNextStepIndex(oldIndex + 1);
1809 OnFinishButtonClick(args);
1810 handled = true;
1811 } else if (String.Equals(MoveToCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
1812 newIndex = Int32.Parse((String)ce.CommandArgument, CultureInfo.InvariantCulture);
1813 args.SetNextStepIndex(newIndex);
1815 handled = true;
1818 if (handled) {
1819 if (!args.Cancel) {
1820 // Honor user's change if activeStepIndex is set explicitely;
1821 if (!_activeStepIndexSet) {
1822 // Make sure the next step is valid to navigate to
1823 if (AllowNavigationToStep(args.NextStepIndex)) {
1824 if (previousButtonCommand) {
1825 GetPreviousStepIndex(true);
1828 ActiveStepIndex = args.NextStepIndex;
1831 } else {
1832 // revert active step if it's cancelled.
1833 ActiveStepIndex = oldIndex;
1838 return handled;
1841 internal void OnWizardStepsChanged() {
1842 SetStepsAndDataBindSideBarList(_sideBarList);
1846 protected virtual bool AllowNavigationToStep(int index) {
1847 if (_historyStack != null && _historyStack.Contains(index)) {
1848 return WizardSteps[index].AllowReturn;
1850 return true;
1854 protected virtual void OnCancelButtonClick(EventArgs e) {
1855 EventHandler handler = (EventHandler)Events[_eventCancelButtonClick];
1856 if (handler != null) {
1857 handler(this, e);
1860 string cancelDestinationUrl = CancelDestinationPageUrl;
1861 if (!String.IsNullOrEmpty(cancelDestinationUrl)) {
1862 Page.Response.Redirect(ResolveClientUrl(cancelDestinationUrl), false);
1867 private void OnCommand(object sender, CommandEventArgs e) {
1868 Debug.Assert(_commandSender == null);
1869 _commandSender = sender as IButtonControl;
1873 protected virtual void OnFinishButtonClick(WizardNavigationEventArgs e) {
1874 WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventFinishButtonClick];
1875 if (handler != null) handler(this, e);
1877 string finishPageUrl = FinishDestinationPageUrl;
1878 if (!String.IsNullOrEmpty(finishPageUrl)) {
1879 // Microsoft suggested that we should not terminate execution of current page, to give
1880 // page a chance to cleanup its resources. This may be less performant though.
1881 // Microsoft suggested that we need to call ResolveClientUrl before redirecting.
1882 // Example is this control inside user control, want redirect relative to user control dir.
1883 Page.Response.Redirect(ResolveClientUrl(finishPageUrl), false);
1888 protected internal override void OnInit(EventArgs e) {
1889 base.OnInit(e);
1891 // Always set the current step to the first step if not specified.
1892 if (ActiveStepIndex == -1 && WizardSteps.Count > 0 && !DesignMode) {
1893 ActiveStepIndex = 0;
1896 // Add default control layout during OnInit to track WizardStep viewstate properly.
1897 EnsureChildControls();
1899 if (Page != null) {
1900 Page.RegisterRequiresControlState(this);
1905 protected virtual void OnNextButtonClick(WizardNavigationEventArgs e) {
1906 WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventNextButtonClick];
1907 if (handler != null) handler(this, e);
1911 protected virtual void OnPreviousButtonClick(WizardNavigationEventArgs e) {
1912 WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventPreviousButtonClick];
1913 if (handler != null) handler(this, e);
1917 protected virtual void OnSideBarButtonClick(WizardNavigationEventArgs e) {
1918 WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventSideBarButtonClick];
1919 if (handler != null) handler(this, e);
1922 internal void RequiresControlsRecreation() {
1923 if (ChildControlsCreated) {
1924 using (new WizardControlCollectionModifier(this)) {
1925 base.ChildControlsCreated = false;
1927 _rendering = null;
1932 protected internal void RegisterCommandEvents(IButtonControl button) {
1933 if (button != null && button.CausesValidation) {
1934 button.Command += new CommandEventHandler(this.OnCommand);
1939 protected internal override void Render(HtmlTextWriter writer) {
1941 // Make sure we're in runat=server form.
1942 if (Page != null) {
1943 Page.VerifyRenderingInServerForm(this);
1946 EnsureChildControls();
1947 ApplyControlProperties();
1949 // Nothing to do if the Wizard is empty;
1950 if (ActiveStepIndex == -1 || WizardSteps.Count == 0) {
1951 return;
1954 RenderContents(writer);
1957 protected internal override object SaveControlState() {
1958 int activeStepIndex = ActiveStepIndex;
1960 // Save the ActiveStepIndex here so steps dynamically added
1961 // before or during OnPagePreRenderComplete will be tracked
1962 // properly. See VSWhidbey 395312
1963 if (_historyStack == null || _historyStack.Count == 0 ||
1964 _historyStack.Peek() != activeStepIndex) {
1965 // Remember the active step.
1966 History.Push(ActiveStepIndex);
1969 object obj = base.SaveControlState();
1971 bool containsHistory = _historyStack != null && _historyStack.Count > 0;
1973 if (obj != null || containsHistory || activeStepIndex != -1) {
1974 object array = containsHistory ? _historyStack.ToArray() : null;
1975 return new Triplet(obj, array, activeStepIndex);
1978 return null;
1982 protected override object SaveViewState() {
1983 object[] myState = new object[_viewStateArrayLength];
1985 Debug.Assert(_viewStateArrayLength == 15, "Forgot to change array length when adding new item to view state?");
1987 myState[0] = base.SaveViewState();
1988 myState[1] = (_navigationButtonStyle != null) ? ((IStateManager)_navigationButtonStyle).SaveViewState() : null;
1989 myState[2] = (_sideBarButtonStyle != null) ? ((IStateManager)_sideBarButtonStyle).SaveViewState() : null;
1990 myState[3] = (_headerStyle != null) ? ((IStateManager)_headerStyle).SaveViewState() : null;
1991 myState[4] = (_navigationStyle != null) ? ((IStateManager)_navigationStyle).SaveViewState() : null;
1992 myState[5] = (_sideBarStyle != null) ? ((IStateManager)_sideBarStyle).SaveViewState() : null;
1993 myState[6] = (_stepStyle != null) ? ((IStateManager)_stepStyle).SaveViewState() : null;
1994 myState[7] = (_startNextButtonStyle != null) ? ((IStateManager)_startNextButtonStyle).SaveViewState() : null;
1995 myState[8] = (_stepNextButtonStyle != null) ? ((IStateManager)_stepNextButtonStyle).SaveViewState() : null;
1996 myState[9] = (_stepPreviousButtonStyle != null) ? ((IStateManager)_stepPreviousButtonStyle).SaveViewState() : null;
1997 myState[10] = (_finishPreviousButtonStyle != null) ? ((IStateManager)_finishPreviousButtonStyle).SaveViewState() : null;
1998 myState[11] = (_finishCompleteButtonStyle != null) ? ((IStateManager)_finishCompleteButtonStyle).SaveViewState() : null;
1999 myState[12] = (_cancelButtonStyle != null) ? ((IStateManager)_cancelButtonStyle).SaveViewState() : null;
2000 myState[13] = ControlStyleCreated ? ((IStateManager)ControlStyle).SaveViewState() : null;
2001 if (DisplaySideBar != _displaySideBarDefault) {
2002 myState[14] = DisplaySideBar;
2005 for (int i = 0; i < _viewStateArrayLength; i++) {
2006 if (myState[i] != null) {
2007 return myState;
2011 // More performant to return null than an array of null values
2012 return null;
2016 private void SetCancelButtonVisibility(BaseNavigationTemplateContainer container) {
2017 // Make the parent TD invisible if possible.
2018 Control c = container.CancelButton as Control;
2020 if (c != null) {
2021 Control parent = c.Parent;
2022 if (parent != null) {
2023 Debug.Assert(parent is TableCell);
2024 parent.Visible = DisplayCancelButton;
2027 c.Visible = DisplayCancelButton;
2032 protected override void TrackViewState() {
2033 base.TrackViewState();
2035 if (_navigationButtonStyle != null)
2036 ((IStateManager)_navigationButtonStyle).TrackViewState();
2038 if (_sideBarButtonStyle != null)
2039 ((IStateManager)_sideBarButtonStyle).TrackViewState();
2041 if (_headerStyle != null)
2042 ((IStateManager)_headerStyle).TrackViewState();
2044 if (_navigationStyle != null)
2045 ((IStateManager)_navigationStyle).TrackViewState();
2047 if (_sideBarStyle != null)
2048 ((IStateManager)_sideBarStyle).TrackViewState();
2050 if (_stepStyle != null)
2051 ((IStateManager)_stepStyle).TrackViewState();
2053 if (_startNextButtonStyle != null)
2054 ((IStateManager)_startNextButtonStyle).TrackViewState();
2056 if (_stepPreviousButtonStyle != null)
2057 ((IStateManager)_stepPreviousButtonStyle).TrackViewState();
2059 if (_stepNextButtonStyle != null)
2060 ((IStateManager)_stepNextButtonStyle).TrackViewState();
2062 if (_finishPreviousButtonStyle != null)
2063 ((IStateManager)_finishPreviousButtonStyle).TrackViewState();
2065 if (_finishCompleteButtonStyle != null)
2066 ((IStateManager)_finishCompleteButtonStyle).TrackViewState();
2068 if (_cancelButtonStyle != null)
2069 ((IStateManager)_cancelButtonStyle).TrackViewState();
2071 if (ControlStyleCreated) {
2072 ((IStateManager)ControlStyle).TrackViewState();
2076 private static void ValidateButtonType(ButtonType value) {
2077 if (value < ButtonType.Button || value > ButtonType.Link) {
2078 throw new ArgumentOutOfRangeException("value");
2082 #region Rendering Abstractions
2084 internal abstract class WizardRenderingBase {
2085 private const string _startNavigationTemplateContainerID = "StartNavigationTemplateContainerID";
2086 private const string _stepNavigationTemplateContainerID = "StepNavigationTemplateContainerID";
2087 private const string _finishNavigationTemplateContainerID = "FinishNavigationTemplateContainerID";
2089 private NavigationTemplate _defaultStartNavigationTemplate;
2090 private NavigationTemplate _defaultStepNavigationTemplate;
2091 private NavigationTemplate _defaultFinishNavigationTemplate;
2093 protected BaseNavigationTemplateContainer _finishNavigationTemplateContainer;
2094 protected BaseNavigationTemplateContainer _startNavigationTemplateContainer;
2095 protected BaseNavigationTemplateContainer _stepNavigationTemplateContainer;
2097 protected Wizard Owner { get; private set; }
2099 protected WizardRenderingBase(Wizard wizard) {
2100 Owner = wizard;
2103 public abstract void ApplyControlProperties();
2105 public abstract void CreateControlHierarchy();
2107 public virtual void SetDesignModeState(IDictionary dictionary) {
2108 if (_startNavigationTemplateContainer != null) {
2109 dictionary[StartNextButtonID] = _startNavigationTemplateContainer.NextButton;
2110 dictionary[CancelButtonID] = _startNavigationTemplateContainer.CancelButton;
2113 if (_stepNavigationTemplateContainer != null) {
2114 dictionary[StepNextButtonID] = _stepNavigationTemplateContainer.NextButton;
2115 dictionary[StepPreviousButtonID] = _stepNavigationTemplateContainer.PreviousButton;
2116 dictionary[CancelButtonID] = _stepNavigationTemplateContainer.CancelButton;
2119 if (_finishNavigationTemplateContainer != null) {
2120 dictionary[FinishPreviousButtonID] = _finishNavigationTemplateContainer.PreviousButton;
2121 dictionary[FinishButtonID] = _finishNavigationTemplateContainer.FinishButton;
2122 dictionary[CancelButtonID] = _finishNavigationTemplateContainer.CancelButton;
2127 protected void ApplyControlProperties_Sidebar() {
2128 if (Owner.SideBarEnabled) {
2129 Owner.SetStepsAndDataBindSideBarList(Owner._sideBarList);
2131 // Only apply the styles to the sidebar or sidebar buttons if custom template is not used.
2132 if (Owner.SideBarTemplate == null) {
2133 foreach (Control item in Owner._sideBarList.Items) {
2134 WebControl button = item.FindControl(SideBarButtonID) as WebControl;
2135 if (button != null) {
2136 button.MergeStyle(Owner._sideBarButtonStyle);
2144 protected void ApplyNavigationTemplateProperties() {
2145 // Do not apply any template properties if the containers are null
2146 // This happens when GetDesignModeState is called before child controls are created.
2147 if (_finishNavigationTemplateContainer == null ||
2148 _startNavigationTemplateContainer == null ||
2149 _stepNavigationTemplateContainer == null) {
2150 return;
2153 WizardStepType renderType = WizardStepType.Start;
2154 // Set the active templates based on ActiveStep
2155 // Make sure the activestepindex is valid. // VSWhidbey 376438
2156 if (Owner.ActiveStepIndex >= Owner.WizardSteps.Count || Owner.ActiveStepIndex < 0) {
2157 return;
2160 renderType = SetActiveTemplates();
2162 bool requiresFinishPreviousButton =
2163 renderType != WizardStepType.Finish || Owner.ActiveStepIndex != 0 || Owner.ActiveStep.StepType != WizardStepType.Auto;
2165 ApplyDefaultStartNavigationTemplateProperties();
2167 bool showPrevious = true;
2168 int prevStepIndex = Owner.GetPreviousStepIndex(false);
2169 if (prevStepIndex >= 0) {
2170 showPrevious = Owner.WizardSteps[prevStepIndex].AllowReturn;
2173 ApplyDefaultFinishNavigationTemplateProperties(showPrevious);
2174 ApplyDefaultStepNavigationTemplateProperties(showPrevious);
2176 // if the first step using auto type is assigned to a finish step, do not render the previous button's container.
2177 if (!requiresFinishPreviousButton) {
2178 Control ctrl = _finishNavigationTemplateContainer.PreviousButton as Control;
2179 if (ctrl != null) {
2180 if (Owner.FinishNavigationTemplate == null) {
2181 ctrl.Parent.Visible = false;
2182 } else {
2183 ctrl.Visible = false;
2189 private void ApplyDefaultStepNavigationTemplateProperties(bool previousImageButtonVisible) {
2190 // Only apply properties to the default template (if a custom template has not been specified)
2191 if (Owner.StepNavigationTemplate != null) {
2192 return;
2195 var navContainer = _stepNavigationTemplateContainer;
2196 NavigationTemplate defaultTemplate = _defaultStepNavigationTemplate;
2198 if (Owner.DesignMode) {
2199 defaultTemplate.ResetButtonsVisibility();
2202 navContainer.PreviousButton = defaultTemplate.FirstButton;
2203 ((Control)navContainer.PreviousButton).Visible = true;
2205 navContainer.NextButton = defaultTemplate.SecondButton;
2206 ((Control)navContainer.NextButton).Visible = true;
2208 navContainer.CancelButton = defaultTemplate.CancelButton;
2210 ApplyButtonProperties(navContainer.NextButton, Owner.StepNextButtonText, Owner.StepNextButtonImageUrl);
2212 ApplyButtonProperties(navContainer.PreviousButton, Owner.StepPreviousButtonText, Owner.StepPreviousButtonImageUrl, previousImageButtonVisible);
2214 ApplyButtonProperties(navContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
2216 int previousStepIndex = Owner.GetPreviousStepIndex(false);
2217 if (previousStepIndex != -1 && !Owner.WizardSteps[previousStepIndex].AllowReturn) {
2218 ((Control)navContainer.PreviousButton).Visible = false;
2221 Owner.SetCancelButtonVisibility(navContainer);
2222 navContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.StepPreviousButtonStyle, Owner.StepNextButtonStyle, Owner.CancelButtonStyle);
2225 private void ApplyDefaultFinishNavigationTemplateProperties(bool previousImageButtonVisible) {
2226 // Only apply properties to the default template (if a custom template has not been specified)
2227 if (Owner.FinishNavigationTemplate != null) {
2228 return;
2231 var finishContainer = _finishNavigationTemplateContainer;
2232 NavigationTemplate defaultTemplate = _defaultFinishNavigationTemplate;
2234 if (Owner.DesignMode) {
2235 defaultTemplate.ResetButtonsVisibility();
2238 finishContainer.PreviousButton = defaultTemplate.FirstButton;
2239 ((Control)finishContainer.PreviousButton).Visible = true;
2241 finishContainer.FinishButton = defaultTemplate.SecondButton;
2242 ((Control)finishContainer.FinishButton).Visible = true;
2244 finishContainer.CancelButton = defaultTemplate.CancelButton;
2246 finishContainer.FinishButton.CommandName = MoveCompleteCommandName;
2248 ApplyButtonProperties(finishContainer.FinishButton, Owner.FinishCompleteButtonText, Owner.FinishCompleteButtonImageUrl);
2250 ApplyButtonProperties(finishContainer.PreviousButton, Owner.FinishPreviousButtonText, Owner.FinishPreviousButtonImageUrl, previousImageButtonVisible);
2252 ApplyButtonProperties(finishContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
2254 int previousStepIndex = Owner.GetPreviousStepIndex(false);
2255 if (previousStepIndex != -1 && !Owner.WizardSteps[previousStepIndex].AllowReturn) {
2256 ((Control)finishContainer.PreviousButton).Visible = false;
2259 Owner.SetCancelButtonVisibility(finishContainer);
2260 finishContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.FinishPreviousButtonStyle, Owner.StepNextButtonStyle, Owner.CancelButtonStyle);
2263 private void ApplyDefaultStartNavigationTemplateProperties() {
2264 // Only apply properties to the default template (if a custom template has not been specified)
2265 if (Owner.StartNavigationTemplate != null) {
2266 return;
2269 var startContainer = _startNavigationTemplateContainer;
2270 NavigationTemplate defaultStartTemplate = _defaultStartNavigationTemplate;
2272 if (Owner.DesignMode) {
2273 defaultStartTemplate.ResetButtonsVisibility();
2276 startContainer.NextButton = defaultStartTemplate.SecondButton;
2277 ((Control)startContainer.NextButton).Visible = true;
2279 startContainer.CancelButton = defaultStartTemplate.CancelButton;
2281 ApplyButtonProperties(startContainer.NextButton, Owner.StartNextButtonText, Owner.StartNextButtonImageUrl);
2283 ApplyButtonProperties(startContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
2285 Owner.SetCancelButtonVisibility(startContainer);
2286 startContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.StepPreviousButtonStyle, Owner.StartNextButtonStyle, Owner.CancelButtonStyle);
2290 protected virtual WizardStepType SetActiveTemplates() {
2291 WizardStepType type = Owner.GetStepType(Owner.ActiveStepIndex);
2293 _startNavigationTemplateContainer.Visible = (type == WizardStepType.Start);
2294 _stepNavigationTemplateContainer.Visible = (type == WizardStepType.Step);
2295 _finishNavigationTemplateContainer.Visible = (type == WizardStepType.Finish);
2297 // Do not render header or sidebarlist in complete steps;
2298 if (type == WizardStepType.Complete) {
2299 OnlyShowCompleteStep();
2302 return type;
2305 private static void ApplyButtonProperties(IButtonControl button, string text, string imageUrl) {
2306 ApplyButtonProperties(button, text, imageUrl, true);
2309 private static void ApplyButtonProperties(IButtonControl button, string text, string imageUrl, bool imageButtonVisible) {
2310 if (button == null) {
2311 return;
2314 ImageButton imageButton = button as ImageButton;
2315 if (imageButton != null) {
2316 imageButton.ImageUrl = imageUrl;
2317 imageButton.AlternateText = text;
2318 imageButton.Visible = imageButtonVisible;
2319 } else {
2320 button.Text = text;
2324 public abstract void OnlyShowCompleteStep();
2326 protected void ApplyCustomNavigationTemplateProperties() {
2327 // Make all custom navigation containers invisible
2328 foreach (BaseNavigationTemplateContainer c in Owner.CustomNavigationContainers.Values) {
2329 c.Visible = false;
2332 // If we are going to show a custom navigation template, make that one visible
2333 if (Owner.ShowCustomNavigationTemplate) {
2334 BaseNavigationTemplateContainer container = Owner._customNavigationContainers[Owner.ActiveStep];
2335 container.Visible = true;
2336 _startNavigationTemplateContainer.Visible = false;
2337 _stepNavigationTemplateContainer.Visible = false;
2338 _finishNavigationTemplateContainer.Visible = false;
2343 protected void CreateControlHierarchy_CleanUpOldSideBarList(IWizardSideBarListControl sideBarList) {
2344 // Remove obsolete events from sideBarDataList
2345 if (sideBarList != null) {
2346 sideBarList.ItemCommand -= new CommandEventHandler(Owner.DataListItemCommand);
2347 sideBarList.ItemDataBound -= new EventHandler<WizardSideBarListControlItemEventArgs>(Owner.DataListItemDataBound);
2351 protected IWizardSideBarListControl CreateControlHierarchy_SetUpSideBarList(Control sideBarContainer) {
2352 var sideBarList = sideBarContainer.FindControl(DataListID) as IWizardSideBarListControl;
2353 if (sideBarList != null) {
2354 sideBarList.ItemCommand += new CommandEventHandler(Owner.DataListItemCommand);
2355 sideBarList.ItemDataBound += new EventHandler<WizardSideBarListControlItemEventArgs>(Owner.DataListItemDataBound);
2356 if (Owner.DesignMode) {
2357 // This line is necessary for ListView to databind correctly to the list of steps when
2358 // viewing the control on the design surface. ListView will not databind automatically when
2359 // it is not a top-level control (as is the case here) unless the flag has a value.
2360 ((IControlDesignerAccessor)sideBarList).GetDesignModeState()["EnableDesignTimeDataBinding"] = true;
2362 Owner.SetStepsAndDataBindSideBarList(sideBarList);
2363 } else {
2364 // Do not throw at designmode otherwise template will not be persisted correctly.
2365 if (!Owner.DesignMode) {
2366 throw new InvalidOperationException(
2367 SR.GetString(SR.Wizard_DataList_Not_Found, DataListID));
2371 return sideBarList;
2375 // Helper method to create navigation templates.
2376 protected void CreateNavigationControlHierarchy(Control container) {
2377 container.Controls.Clear();
2378 Owner.CustomNavigationContainers.Clear();
2379 Owner.CreateCustomNavigationTemplates();
2381 foreach (BaseNavigationTemplateContainer c in Owner.CustomNavigationContainers.Values) {
2382 container.Controls.Add(c);
2385 CreateStartNavigationTemplate(container);
2386 CreateFinishNavigationTemplate(container);
2387 CreateStepNavigationTemplate(container);
2391 private void CreateStartNavigationTemplate(Control container) {
2392 // Start navigation template
2393 ITemplate startNavigationTemplate = Owner.StartNavigationTemplate;
2394 _startNavigationTemplateContainer = new StartNavigationTemplateContainer(Owner);
2395 _startNavigationTemplateContainer.ID = _startNavigationTemplateContainerID;
2397 // Use the default template
2398 if (startNavigationTemplate == null) {
2399 _startNavigationTemplateContainer.EnableViewState = false;
2400 _defaultStartNavigationTemplate = NavigationTemplate.GetDefaultStartNavigationTemplate(Owner);
2401 startNavigationTemplate = _defaultStartNavigationTemplate;
2402 } else {
2403 // Custom template is used here.
2404 _startNavigationTemplateContainer.SetEnableTheming();
2407 startNavigationTemplate.InstantiateIn(_startNavigationTemplateContainer);
2408 container.Controls.Add(_startNavigationTemplateContainer);
2411 private void CreateStepNavigationTemplate(Control container) {
2412 // step navigation template
2413 ITemplate stepNavigationTemplate = Owner.StepNavigationTemplate;
2414 _stepNavigationTemplateContainer = new StepNavigationTemplateContainer(Owner);
2415 _stepNavigationTemplateContainer.ID = _stepNavigationTemplateContainerID;
2417 if (stepNavigationTemplate == null) {
2418 _stepNavigationTemplateContainer.EnableViewState = false;
2419 _defaultStepNavigationTemplate = NavigationTemplate.GetDefaultStepNavigationTemplate(Owner);
2420 stepNavigationTemplate = _defaultStepNavigationTemplate;
2421 } else {
2422 _stepNavigationTemplateContainer.SetEnableTheming();
2425 stepNavigationTemplate.InstantiateIn(_stepNavigationTemplateContainer);
2426 container.Controls.Add(_stepNavigationTemplateContainer);
2429 private void CreateFinishNavigationTemplate(Control container) {
2430 // finish navigation template
2431 ITemplate finishNavigationTemplate = Owner.FinishNavigationTemplate;
2432 _finishNavigationTemplateContainer = new FinishNavigationTemplateContainer(Owner);
2433 _finishNavigationTemplateContainer.ID = _finishNavigationTemplateContainerID;
2435 if (finishNavigationTemplate == null) {
2436 _finishNavigationTemplateContainer.EnableViewState = false;
2437 _defaultFinishNavigationTemplate = NavigationTemplate.GetDefaultFinishNavigationTemplate(Owner);
2438 finishNavigationTemplate = _defaultFinishNavigationTemplate;
2439 } else {
2440 _finishNavigationTemplateContainer.SetEnableTheming();
2443 finishNavigationTemplate.InstantiateIn(_finishNavigationTemplateContainer);
2444 container.Controls.Add(_finishNavigationTemplateContainer);
2448 internal class LayoutTemplateWizardRendering : WizardRenderingBase {
2450 private Literal _headerLiteral;
2451 private WizardContainer _layoutContainer;
2453 public LayoutTemplateWizardRendering(Wizard wizard)
2454 : base(wizard) {
2457 public override void ApplyControlProperties() {
2458 ApplyControlProperties_Header();
2459 ApplyControlProperties_Sidebar();
2460 // nothing interesting to apply to the wizard steps
2461 ApplyControlProperties_Navigation();
2464 private void ApplyControlProperties_Navigation() {
2465 ApplyNavigationTemplateProperties();
2466 ApplyCustomNavigationTemplateProperties();
2469 private void ApplyControlProperties_Header() {
2470 if (Owner.HeaderTemplate != null) {
2471 // nothing to apply if there is a header template
2472 return;
2475 if (_headerLiteral != null) {
2476 // not necessary to set the literal to not visible if the text is empty because a
2477 // literal with empty text does not render anything
2478 _headerLiteral.Text = Owner.HeaderText;
2479 } else if (!String.IsNullOrEmpty(Owner.HeaderText)) {
2480 // only throw if the headertext is set and there is no headerLiteral. This means
2481 // that the layout template did not contain a header placeholder.
2483 throw new InvalidOperationException(SR.GetString(SR.Wizard_Header_Placeholder_Must_Be_Specified_For_HeaderText, Owner.ID, HeaderPlaceholderId));
2488 public override void OnlyShowCompleteStep() {
2489 _layoutContainer.ControlToRender = Owner.MultiView;
2493 public override void CreateControlHierarchy() {
2494 _layoutContainer = new WizardContainer();
2495 Owner.LayoutTemplate.InstantiateIn(_layoutContainer);
2497 using (new WizardControlCollectionModifier(Owner)) {
2498 Owner.Controls.Add(_layoutContainer);
2501 CreateControlHierarchy_Header(_layoutContainer);
2502 CreateControlHierarchy_SideBar(_layoutContainer);
2503 CreateControlHierarchy_WizardStep(_layoutContainer);
2504 CreateControlHierarchy_Navigation(_layoutContainer);
2507 private void CreateControlHierarchy_Navigation(Control layoutContainer) {
2508 var placeholder = layoutContainer.FindControl(NavigationPlaceholderId);
2509 if (placeholder == null) {
2510 throw new InvalidOperationException(SR.GetString(SR.Wizard_Navigation_Placeholder_Must_Be_Specified, Owner.ID, NavigationPlaceholderId));
2513 Control navigationContainer = new Control();
2515 ReplacePlaceholderWithControl(layoutContainer, placeholder, navigationContainer);
2516 CreateNavigationControlHierarchy(navigationContainer);
2519 private void CreateControlHierarchy_Header(Control layoutContainer) {
2520 var placeholder = layoutContainer.FindControl(HeaderPlaceholderId);
2522 if (Owner.HeaderTemplate != null) {
2523 if (placeholder == null) {
2524 throw new InvalidOperationException(SR.GetString(SR.Wizard_Header_Placeholder_Must_Be_Specified_For_HeaderTemplate, Owner.ID, HeaderPlaceholderId));
2525 } else {
2526 // just replace the placeholder with the template
2527 ReplacePlaceholderWithTemplateInstance(layoutContainer, placeholder, Owner.HeaderTemplate);
2529 } else if (placeholder != null) {
2530 // only create a header literal if the template contains a placeholder
2531 // if the template does not contain a placeholder an exception will be thrown from
2532 // ApplyControlProperties
2533 _headerLiteral = new Literal();
2534 ReplacePlaceholderWithControl(layoutContainer, placeholder, _headerLiteral);
2538 private void CreateControlHierarchy_SideBar(Control layoutContainer) {
2539 if (!Owner.DisplaySideBar) {
2540 // it's ok to exit here since changing the DisplaySideBar value would
2541 // force a recreation of the control tree.
2542 return;
2545 var placeholder = layoutContainer.FindControl(SideBarPlaceholderId);
2547 if (placeholder == null) {
2549 throw new InvalidOperationException(SR.GetString(SR.Wizard_Sidebar_Placeholder_Must_Be_Specified, Owner.ID, SideBarPlaceholderId));
2552 ITemplate sideBarTemplate = Owner.SideBarTemplate ?? Owner.CreateDefaultSideBarTemplate();
2554 ReplacePlaceholderWithTemplateInstance(layoutContainer, placeholder, sideBarTemplate);
2556 CreateControlHierarchy_CleanUpOldSideBarList(Owner.SideBarList);
2557 Owner._sideBarList = CreateControlHierarchy_SetUpSideBarList(layoutContainer);
2560 private void CreateControlHierarchy_WizardStep(Control layoutContainer) {
2561 var placeholder = layoutContainer.FindControl(WizardStepPlaceholderId);
2563 if (placeholder == null) {
2564 throw new InvalidOperationException(SR.GetString(SR.Wizard_Step_Placeholder_Must_Be_Specified, Owner.ID, WizardStepPlaceholderId));
2567 ReplacePlaceholderWithControl(layoutContainer, placeholder, Owner.MultiView);
2570 private static void ReplacePlaceholderWithTemplateInstance(Control targetContainer, Control placeholder, ITemplate template) {
2571 var templateContainer = new Control();
2572 template.InstantiateIn(templateContainer);
2574 ReplacePlaceholderWithControl(targetContainer, placeholder, templateContainer);
2577 private static void ReplacePlaceholderWithControl(Control targetContainer, Control placeholder, Control replacement) {
2578 var placeholderIndex = targetContainer.Controls.IndexOf(placeholder);
2579 targetContainer.Controls.RemoveAt(placeholderIndex);
2581 targetContainer.Controls.AddAt(placeholderIndex, replacement);
2584 internal class WizardContainer : WebControl {
2585 internal Control ControlToRender { get; set; }
2587 protected internal override void Render(HtmlTextWriter writer) {
2588 if (ControlToRender == null) {
2589 RenderChildren(writer);
2590 } else {
2591 ControlToRender.Render(writer);
2597 internal class TableWizardRendering : WizardRenderingBase {
2598 private const string _headerCellID = "HeaderContainer";
2599 private const string _sideBarCellID = "SideBarContainer";
2600 private const string _stepTableCellID = "StepTableCell";
2602 private TableCell _headerTableCell;
2603 private TableRow _headerTableRow;
2604 private TableRow _navigationRow;
2605 private TableCell _navigationTableCell;
2606 private Table _renderTable;
2607 private TableCell _stepTableCell;
2609 private LiteralControl _titleLiteral;
2611 public TableWizardRendering(Wizard wizard)
2612 : base(wizard) {
2615 // Returns the cell which the navigation template container should be added to
2616 private TableCell NavigationTableCell {
2617 get {
2618 if (_navigationTableCell == null) {
2619 _navigationTableCell = new TableCell();
2621 return _navigationTableCell;
2625 public override void ApplyControlProperties() {
2626 // Nothing to do if the Wizard is empty;
2627 // Apply the control properties at designtime so that controls inside templates are styled properly.
2628 if (!Owner.DesignMode &&
2629 (Owner.ActiveStepIndex < 0 || Owner.ActiveStepIndex >= Owner.WizardSteps.Count || Owner.WizardSteps.Count == 0)) {
2630 return;
2633 if (Owner.SideBarEnabled && Owner._sideBarStyle != null) {
2634 // Apply Sidebar style on the table cell VSWhidbey 377064
2635 Owner._sideBarTableCell.ApplyStyle(Owner._sideBarStyle);
2638 ApplyControlProperties_Header();
2640 ApplyControlProperties_WizardSteps();
2642 ApplyControlProperties_Navigation();
2644 ApplyControlProperties_Sidebar();
2646 if (_renderTable != null) {
2647 // Clear out the accesskey/tab index so it doesn't get applied to the tables in the container
2648 Util.CopyBaseAttributesToInnerControl(Owner, _renderTable);
2650 if (Owner.ControlStyleCreated) {
2651 _renderTable.ApplyStyle(Owner.ControlStyle);
2652 } else {
2653 // initialize defaults that are different from TableStyle
2654 _renderTable.CellSpacing = 0;
2655 _renderTable.CellPadding = 0;
2658 // On Mac IE, if height is not set, render height:1px, so the table sizes to contents.
2659 // Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
2660 if (!Owner.DesignMode && Owner.IsMacIE5 &&
2661 (!Owner.ControlStyleCreated || Owner.ControlStyle.Height == Unit.Empty)) {
2662 _renderTable.ControlStyle.Height = Unit.Pixel(1);
2666 // On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
2667 // Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
2668 if (!Owner.DesignMode && _navigationTableCell != null && Owner.IsMacIE5) {
2669 _navigationTableCell.ControlStyle.Height = Unit.Pixel(1);
2674 private void ApplyControlProperties_Navigation() {
2675 ApplyNavigationTemplateProperties();
2676 ApplyCustomNavigationTemplateProperties();
2678 if (_navigationTableCell != null) {
2679 NavigationTableCell.HorizontalAlign = HorizontalAlign.Right;
2680 // Copy the styles from the StepStyle property if defined.
2681 if (Owner._navigationStyle != null) {
2682 if (!Owner.DesignMode && Owner.IsMacIE5 && Owner._navigationStyle.Height == Unit.Empty) {
2683 Owner._navigationStyle.Height = Unit.Pixel(1);
2686 _navigationTableCell.ApplyStyle(Owner._navigationStyle);
2690 if (Owner.ShowCustomNavigationTemplate) {
2691 // Make sure the navigation row is visible
2692 _navigationRow.Visible = true;
2696 private void ApplyControlProperties_WizardSteps() {
2697 // Apply the WizardSteps style
2698 if (_stepTableCell != null) {
2699 // Copy the styles from the StepStyle property if defined.
2700 if (Owner._stepStyle != null) {
2701 if (!Owner.DesignMode && Owner.IsMacIE5 && Owner._stepStyle.Height == Unit.Empty) {
2702 Owner._stepStyle.Height = Unit.Pixel(1);
2705 _stepTableCell.ApplyStyle(Owner._stepStyle);
2710 private void ApplyControlProperties_Header() {
2711 if (_headerTableRow != null) {
2712 // If headerTemplate is not defined and headertext is empty, do not render the
2713 // empty table row.
2714 if ((Owner.HeaderTemplate == null) && String.IsNullOrEmpty(Owner.HeaderText)) {
2715 _headerTableRow.Visible = false;
2716 } else {
2717 _headerTableCell.ApplyStyle(Owner._headerStyle);
2719 // if HeaderTemplate is defined.
2720 if (Owner.HeaderTemplate != null) {
2721 if (_titleLiteral != null) {
2722 _titleLiteral.Visible = false;
2725 // Otherwise HeaderText is defined.
2726 else {
2727 Debug.Assert(Owner.HeaderText != null && Owner.HeaderText.Length > 0);
2728 if (_titleLiteral != null) {
2729 _titleLiteral.Text = Owner.HeaderText;
2737 protected override WizardStepType SetActiveTemplates() {
2738 WizardStepType type = base.SetActiveTemplates();
2740 if (type != WizardStepType.Complete) {
2741 // Only render sidebartablecell if necessary
2742 if (Owner._sideBarTableCell != null) {
2743 Owner._sideBarTableCell.Visible = Owner.SideBarEnabled && Owner._renderSideBarDataList;
2747 return type;
2750 public override void OnlyShowCompleteStep() {
2751 // Do not render header or sidebarlist in complete steps;
2752 if (_headerTableRow != null) {
2753 _headerTableRow.Visible = false;
2756 if (Owner._sideBarTableCell != null) {
2757 Owner._sideBarTableCell.Visible = false;
2760 _navigationRow.Visible = false;
2764 public override void CreateControlHierarchy() {
2765 // Use the inner table to render header template, step and navigation template
2766 Table mainContentTable = null;
2768 if (Owner.DisplaySideBar) {
2769 mainContentTable = CreateControlHierarchy_CreateLayoutWithSideBar();
2770 } else {
2771 mainContentTable = CreateControlHierarchy_CreateLayoutWithoutSideBar();
2774 CreateControlHierarchy_CreateHeaderArea(mainContentTable);
2776 CreateControlHierarchy_CreateStepArea(mainContentTable);
2778 CreateControlHierarchy_CreateNavigationArea(mainContentTable);
2782 private void CreateControlHierarchy_CreateNavigationArea(Table mainContentTable) {
2783 _navigationRow = new TableRow();
2784 mainContentTable.Controls.Add(_navigationRow);
2785 _navigationRow.Controls.Add(NavigationTableCell);
2787 CreateNavigationControlHierarchy(NavigationTableCell);
2790 private void CreateControlHierarchy_CreateStepArea(Table mainContentTable) {
2791 TableRow stepRow = new TableRow() {
2792 // The step row needs to use the most of the table size.
2793 Height = Unit.Percentage(100)
2795 mainContentTable.Controls.Add(stepRow);
2796 _stepTableCell = new TableCell();
2798 stepRow.Controls.Add(_stepTableCell);
2800 _stepTableCell.Controls.Add(Owner.MultiView);
2802 Owner.InstantiateStepContentTemplates();
2805 private void CreateControlHierarchy_CreateHeaderArea(Table mainContentTable) {
2806 _headerTableRow = new TableRow();
2807 mainContentTable.Controls.Add(_headerTableRow);
2808 _headerTableCell = new InternalTableCell(Owner) {
2809 ID = _headerCellID
2812 if (Owner.HeaderTemplate != null) {
2813 _headerTableCell.EnableTheming = Owner.EnableTheming;
2814 Owner.HeaderTemplate.InstantiateIn(_headerTableCell);
2815 } else {
2816 // Render the title property if HeaderTemplate is not defined.
2817 _titleLiteral = new LiteralControl();
2818 _headerTableCell.Controls.Add(_titleLiteral);
2821 _headerTableRow.Controls.Add(_headerTableCell);
2824 private Table CreateControlHierarchy_CreateLayoutWithoutSideBar() {
2825 // if sidebar is disabled, add mainContentTable directly into the Wizard control.
2826 var mainContentTable = new WizardChildTable(Owner) {
2827 EnableTheming = false
2829 using (new WizardControlCollectionModifier(Owner)) {
2830 Owner.Controls.Add(mainContentTable);
2832 _renderTable = mainContentTable;
2833 return mainContentTable;
2836 private Table CreateControlHierarchy_CreateLayoutWithSideBar() {
2837 // Create an outer table and make all child controls into the right cell.
2838 // Use the left cell to render the side bar.
2840 Table outerTable = new WizardChildTable(Owner) {
2841 EnableTheming = false
2844 TableRow outerRow = new TableRow();
2845 outerTable.Controls.Add(outerRow);
2847 // Use the existing sideBarTableCell if possible.
2848 TableCell outerLeftCell = Owner._sideBarTableCell ?? CreateControlHierarchy_CreateSideBarTableCell();
2849 outerRow.Controls.Add(outerLeftCell);
2851 Owner._sideBarTableCell = outerLeftCell;
2852 Owner._renderSideBarDataList = false;
2854 // Right cell is used for header, step and navigation areas.
2855 TableCell outerRightCell = new TableCell() {
2856 // Maximize the inner default table Whidbey 143409.
2857 Height = Unit.Percentage(100)
2860 outerRow.Controls.Add(outerRightCell);
2862 var mainContentTable = new WizardDefaultInnerTable() {
2863 CellSpacing = 0,
2864 Height = Unit.Percentage(100),
2865 Width = Unit.Percentage(100)
2868 outerRightCell.Controls.Add(mainContentTable);
2870 // On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
2871 // Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
2872 if (!Owner.DesignMode && Owner.IsMacIE5) {
2873 outerRightCell.Height = Unit.Pixel(1);
2876 // Add the table into the Wizard control
2877 using (new WizardControlCollectionModifier(Owner)) {
2878 Owner.Controls.Add(outerTable);
2881 CreateControlHierarchy_CleanUpOldSideBarList(Owner.SideBarList);
2882 Owner._sideBarList = CreateControlHierarchy_SetUpSideBarList(Owner._sideBarTableCell);
2884 _renderTable = outerTable;
2885 return mainContentTable;
2888 private TableCell CreateControlHierarchy_CreateSideBarTableCell() {
2889 // Left cell is used for SideBar
2890 TableCell outerLeftCell = new AccessibleTableCell(Owner) {
2891 ID = _sideBarCellID,
2892 // Left cell should expand to all height if sidebar is displayed.
2893 Height = Unit.Percentage(100)
2896 ITemplate sideBarTemplate = Owner.SideBarTemplate;
2898 if (sideBarTemplate == null) {
2899 outerLeftCell.EnableViewState = false;
2900 sideBarTemplate = Owner.CreateDefaultSideBarTemplate();
2901 } else {
2902 outerLeftCell.EnableTheming = Owner.EnableTheming;
2904 sideBarTemplate.InstantiateIn(outerLeftCell);
2906 return outerLeftCell;
2910 public override void SetDesignModeState(IDictionary dictionary) {
2911 base.SetDesignModeState(dictionary);
2912 dictionary[_stepTableCellID] = _stepTableCell;
2917 #endregion
2919 private class WizardControlCollection : ControlCollection {
2920 public WizardControlCollection(Wizard wizard)
2921 : base(wizard) {
2922 if (!wizard.DesignMode)
2923 SetCollectionReadOnly(SR.Wizard_Cannot_Modify_ControlCollection);
2927 private class WizardControlCollectionModifier : IDisposable {
2928 Wizard _wizard;
2929 ControlCollection _controls;
2930 String _originalError;
2932 public WizardControlCollectionModifier(Wizard wizard) {
2933 _wizard = wizard;
2934 if (!_wizard.DesignMode) {
2935 // Remember the ControlCollection so we don't need to access the
2936 // Controls property by GC during Dispose. Accessing this property has the
2937 // side-effect of creating the entire child controls on CompositeControl.
2938 _controls = _wizard.Controls;
2939 _originalError = _controls.SetCollectionReadOnly(null);
2943 void IDisposable.Dispose() {
2944 if (!_wizard.DesignMode) {
2945 _controls.SetCollectionReadOnly(_originalError);
2950 [SupportsEventValidation]
2951 private class WizardChildTable : ChildTable {
2952 private Wizard _owner;
2954 internal WizardChildTable(Wizard owner) {
2955 _owner = owner;
2958 protected override bool OnBubbleEvent(object source, EventArgs args) {
2959 return _owner.OnBubbleEvent(source, args);
2963 private enum WizardTemplateType {
2964 StartNavigationTemplate = 0,
2965 StepNavigationTemplate = 1,
2966 FinishNavigationTemplate = 2,
2969 private sealed class NavigationTemplate : ITemplate {
2971 private Wizard _wizard;
2972 private WizardTemplateType _templateType;
2973 private String _button1ID;
2974 private String _button2ID;
2975 private String _button3ID;
2977 private const string _startNextButtonID = "StartNext";
2978 private const string _stepNextButtonID = "StepNext";
2979 private const string _stepPreviousButtonID = "StepPrevious";
2980 private const string _finishPreviousButtonID = "FinishPrevious";
2981 private const string _finishButtonID = "Finish";
2982 private const string _cancelButtonID = "Cancel";
2984 private TableRow _row;
2986 private IButtonControl[][] _buttons;
2988 private bool _button1CausesValidation;
2990 internal static NavigationTemplate GetDefaultStartNavigationTemplate(Wizard wizard) {
2991 return new NavigationTemplate(wizard, WizardTemplateType.StartNavigationTemplate,
2992 true, null, _startNextButtonID, _cancelButtonID);
2995 internal static NavigationTemplate GetDefaultStepNavigationTemplate(Wizard wizard) {
2996 return new NavigationTemplate(wizard, WizardTemplateType.StepNavigationTemplate,
2997 false, _stepPreviousButtonID, _stepNextButtonID, _cancelButtonID);
3000 internal static NavigationTemplate GetDefaultFinishNavigationTemplate(Wizard wizard) {
3001 return new NavigationTemplate(wizard, WizardTemplateType.FinishNavigationTemplate,
3002 false, _finishPreviousButtonID, _finishButtonID, _cancelButtonID);
3005 internal void ResetButtonsVisibility() {
3006 Debug.Assert(_wizard.DesignMode);
3008 for (int i = 0; i < 3; i++) {
3009 for (int j = 0; j < 3; j++) {
3010 Control c = _buttons[i][j] as Control;
3011 if (c != null) c.Visible = false;
3016 private NavigationTemplate(Wizard wizard, WizardTemplateType templateType, bool button1CausesValidation,
3017 String label1ID, String label2ID, String label3ID) {
3019 _wizard = wizard;
3020 _button1ID = label1ID;
3021 _button2ID = label2ID;
3022 _button3ID = label3ID;
3024 _templateType = templateType;
3026 _buttons = new IButtonControl[3][];
3027 _buttons[0] = new IButtonControl[3];
3028 _buttons[1] = new IButtonControl[3];
3029 _buttons[2] = new IButtonControl[3];
3031 _button1CausesValidation = button1CausesValidation;
3034 void ITemplate.InstantiateIn(Control container) {
3035 Table table = new WizardDefaultInnerTable();
3037 // Increase the default space and padding so the layout
3038 // of the buttons look good. Also, to make custom border
3039 // visible. VSWhidbey 377069
3040 table.CellSpacing = 5;
3041 table.CellPadding = 5;
3042 container.Controls.Add(table);
3044 _row = new TableRow();
3045 table.Rows.Add(_row);
3047 if (_button1ID != null) {
3048 CreateButtonControl(_buttons[0], _button1ID, _button1CausesValidation,
3049 MovePreviousCommandName);
3052 if (_button2ID != null) {
3053 CreateButtonControl(_buttons[1], _button2ID, true /* causesValidation */,
3054 _templateType == WizardTemplateType.FinishNavigationTemplate ? MoveCompleteCommandName : MoveNextCommandName);
3057 CreateButtonControl(_buttons[2], _button3ID, false /* causesValidation */, CancelCommandName);
3060 private void OnPreRender(object source, EventArgs e) {
3061 ((ImageButton)source).Visible = false;
3064 private void CreateButtonControl(IButtonControl[] buttons, String id, bool causesValidation, string commandName) {
3065 LinkButton linkButton = new LinkButton();
3066 linkButton.CausesValidation = causesValidation;
3067 linkButton.ID = id + "LinkButton";
3068 linkButton.Visible = false;
3069 linkButton.CommandName = commandName;
3070 linkButton.TabIndex = _wizard.TabIndex;
3071 _wizard.RegisterCommandEvents(linkButton);
3072 buttons[0] = linkButton;
3074 ImageButton imageButton = new ImageButton();
3075 imageButton.CausesValidation = causesValidation;
3076 imageButton.ID = id + "ImageButton";
3077 imageButton.Visible = true;
3078 imageButton.CommandName = commandName;
3079 imageButton.TabIndex = _wizard.TabIndex;
3080 _wizard.RegisterCommandEvents(imageButton);
3081 imageButton.PreRender += new EventHandler(OnPreRender);
3082 buttons[1] = imageButton;
3084 Button button = new Button();
3085 button.CausesValidation = causesValidation;
3086 button.ID = id + "Button";
3087 button.Visible = false;
3088 button.CommandName = commandName;
3089 button.TabIndex = _wizard.TabIndex;
3090 _wizard.RegisterCommandEvents(button);
3091 buttons[2] = button;
3093 TableCell tableCell = new TableCell();
3094 tableCell.HorizontalAlign = HorizontalAlign.Right;
3095 _row.Cells.Add(tableCell);
3097 tableCell.Controls.Add(linkButton);
3098 tableCell.Controls.Add(imageButton);
3099 tableCell.Controls.Add(button);
3102 internal IButtonControl FirstButton {
3103 get {
3104 ButtonType buttonType = ButtonType.Button;
3105 switch (_templateType) {
3106 case WizardTemplateType.StartNavigationTemplate:
3107 Debug.Fail("Invalid template/button type");
3108 break;
3110 case WizardTemplateType.StepNavigationTemplate:
3111 buttonType = _wizard.StepPreviousButtonType;
3112 break;
3114 case WizardTemplateType.FinishNavigationTemplate:
3115 default:
3116 buttonType = _wizard.FinishPreviousButtonType;
3117 break;
3120 return GetButtonBasedOnType(0, buttonType);
3124 internal IButtonControl SecondButton {
3125 get {
3126 ButtonType buttonType = ButtonType.Button;
3127 switch (_templateType) {
3128 case WizardTemplateType.StartNavigationTemplate:
3129 buttonType = _wizard.StartNextButtonType;
3130 break;
3132 case WizardTemplateType.StepNavigationTemplate:
3133 buttonType = _wizard.StepNextButtonType;
3134 break;
3136 case WizardTemplateType.FinishNavigationTemplate:
3137 default:
3138 buttonType = _wizard.FinishCompleteButtonType;
3139 break;
3142 return GetButtonBasedOnType(1, buttonType);
3146 internal IButtonControl CancelButton {
3147 get {
3148 ButtonType buttonType = _wizard.CancelButtonType;
3149 return GetButtonBasedOnType(2, buttonType);
3153 private IButtonControl GetButtonBasedOnType(int pos, ButtonType type) {
3154 switch (type) {
3155 case ButtonType.Button:
3156 return _buttons[pos][2];
3158 case ButtonType.Image:
3159 return _buttons[pos][1];
3161 case ButtonType.Link:
3162 return _buttons[pos][0];
3165 return null;
3169 private class DataListItemTemplate : ITemplate {
3170 Wizard _owner;
3172 internal DataListItemTemplate(Wizard owner) {
3173 _owner = owner;
3176 public void InstantiateIn(Control container) {
3177 LinkButton linkButton = new LinkButton();
3178 container.Controls.Add(linkButton);
3179 linkButton.ID = SideBarButtonID;
3181 if (_owner.DesignMode) {
3182 linkButton.MergeStyle(_owner.SideBarButtonStyle);
3187 private class DefaultSideBarTemplate : ITemplate {
3188 private Wizard _owner;
3190 internal DefaultSideBarTemplate(Wizard owner) {
3191 _owner = owner;
3194 public void InstantiateIn(Control container) {
3195 Control sideBarListControl = null;
3197 if (_owner.SideBarList == null) {
3198 var dataList = new DataList();
3199 dataList.ID = Wizard.DataListID;
3201 dataList.SelectedItemStyle.Font.Bold = true;
3202 dataList.ItemTemplate = _owner.CreateDefaultDataListItemTemplate();
3204 sideBarListControl = dataList;
3205 } else {
3206 sideBarListControl = (Control)_owner.SideBarList;
3209 container.Controls.Add(sideBarListControl);
3213 // Internally use an empty table (with a row and a cell) to render the content.
3214 internal abstract class BlockControl : WebControl, INamingContainer, INonBindingContainer {
3215 private Table _table;
3216 internal TableCell _cell;
3217 internal Wizard _owner;
3219 internal BlockControl(Wizard owner) {
3220 Debug.Assert(owner != null);
3221 _owner = owner;
3223 _table = new WizardDefaultInnerTable();
3224 _table.EnableTheming = false;
3226 Controls.Add(_table);
3228 TableRow row = new TableRow();
3229 _table.Controls.Add(row);
3231 _cell = new TableCell();
3232 _cell.Height = Unit.Percentage(100);
3233 _cell.Width = Unit.Percentage(100);
3234 row.Controls.Add(_cell);
3236 HandleMacIECellHeight();
3237 PreventAutoID();
3240 protected Table Table {
3241 get { return _table; }
3244 internal TableCell InnerCell {
3245 get { return _cell; }
3248 protected override Style CreateControlStyle() {
3249 return new TableItemStyle(ViewState);
3252 public override void Focus() {
3253 throw new NotSupportedException(SR.GetString(SR.NoFocusSupport, this.GetType().Name));
3256 internal void HandleMacIECellHeight() {
3257 // On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
3258 // Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
3259 if (!_owner.DesignMode && _owner.IsMacIE5) {
3260 _cell.Height = Unit.Pixel(1);
3264 // Renders the inner control only
3265 protected internal override void Render(HtmlTextWriter writer) {
3266 RenderContents(writer);
3269 internal void SetEnableTheming() {
3270 _cell.EnableTheming = _owner.EnableTheming;
3274 private class InternalTableCell : TableCell, INamingContainer, INonBindingContainer {
3275 protected Wizard _owner;
3277 internal InternalTableCell(Wizard owner) {
3278 _owner = owner;
3281 // Do not render any attributes other than Style on this cell.
3282 protected override void AddAttributesToRender(HtmlTextWriter writer) {
3283 if (ControlStyleCreated && !ControlStyle.IsEmpty) {
3284 // let the style add attributes
3285 ControlStyle.AddAttributesToRender(writer, this);
3290 private class AccessibleTableCell : InternalTableCell {
3291 internal AccessibleTableCell(Wizard owner)
3292 : base(owner) {
3295 protected internal override void RenderChildren(HtmlTextWriter writer) {
3296 ControlRenderingHelper.WriteSkipLinkStart(writer, RenderingCompatibility, _owner.DesignMode, _owner.SkipLinkText, SpacerImageUrl, _owner.ClientID);
3298 base.RenderChildren(writer);
3300 ControlRenderingHelper.WriteSkipLinkEnd(writer, _owner.DesignMode, _owner.SkipLinkText, _owner.ClientID);
3304 internal class BaseContentTemplateContainer : BlockControl {
3305 private bool _useInnerTable;
3306 internal BaseContentTemplateContainer(Wizard owner, bool useInnerTable)
3307 : base(owner) {
3308 _useInnerTable = useInnerTable;
3309 if (useInnerTable) {
3310 // Set the table width to 100% so the table within each
3311 // row will have the same width. VSWhidbey 377182
3312 Table.Width = Unit.Percentage(100);
3313 Table.Height = Unit.Percentage(100);
3315 else {
3316 // remove nested table from Control tree
3317 Controls.Clear();
3321 internal void AddChildControl(Control c) {
3322 Container.Controls.Add(c);
3325 internal Control Container {
3326 get {
3327 return _useInnerTable ? InnerCell : (Control)this;
3332 #region Navigation Template Containers
3334 internal class BaseNavigationTemplateContainer : WebControl, INamingContainer, INonBindingContainer {
3335 private IButtonControl _finishButton;
3336 private IButtonControl _previousButton;
3337 private IButtonControl _nextButton;
3338 private IButtonControl _cancelButton;
3339 private Wizard _owner;
3341 internal BaseNavigationTemplateContainer(Wizard owner) {
3342 _owner = owner;
3345 internal Wizard Owner {
3346 get {
3347 return _owner;
3351 internal void ApplyButtonStyle(Style finishStyle, Style prevStyle, Style nextStyle, Style cancelStyle) {
3352 if (FinishButton != null) ApplyButtonStyleInternal(FinishButton, finishStyle);
3353 if (PreviousButton != null) ApplyButtonStyleInternal(PreviousButton, prevStyle);
3354 if (NextButton != null) ApplyButtonStyleInternal(NextButton, nextStyle);
3355 if (CancelButton != null) ApplyButtonStyleInternal(CancelButton, cancelStyle);
3358 protected void ApplyButtonStyleInternal(IButtonControl control, Style buttonStyle) {
3359 WebControl webCtrl = control as WebControl;
3360 if (webCtrl != null) {
3361 webCtrl.ApplyStyle(buttonStyle);
3362 webCtrl.ControlStyle.MergeWith(Owner.NavigationButtonStyle);
3366 public override void Focus() {
3367 throw new NotSupportedException(SR.GetString(SR.NoFocusSupport, this.GetType().Name));
3370 internal void RegisterButtonCommandEvents() {
3371 Owner.RegisterCommandEvents(NextButton);
3372 Owner.RegisterCommandEvents(FinishButton);
3373 Owner.RegisterCommandEvents(PreviousButton);
3374 Owner.RegisterCommandEvents(CancelButton);
3377 internal IButtonControl CancelButton {
3378 get {
3379 if (_cancelButton != null) {
3380 return _cancelButton;
3383 _cancelButton = FindControl(Wizard.CancelButtonID) as IButtonControl;
3384 return _cancelButton;
3387 set {
3388 _cancelButton = value;
3392 internal virtual IButtonControl NextButton {
3393 get {
3394 if (_nextButton != null) {
3395 return _nextButton;
3398 _nextButton = FindControl(Wizard.StepNextButtonID) as IButtonControl;
3399 return _nextButton;
3402 set {
3403 _nextButton = value;
3407 internal virtual IButtonControl PreviousButton {
3408 get {
3409 if (_previousButton != null) {
3410 return _previousButton;
3413 _previousButton = FindControl(Wizard.StepPreviousButtonID) as IButtonControl;
3414 return _previousButton;
3417 set {
3418 _previousButton = value;
3422 internal IButtonControl FinishButton {
3423 get {
3424 if (_finishButton != null) {
3425 return _finishButton;
3428 _finishButton = FindControl(Wizard.FinishButtonID) as IButtonControl;
3429 return _finishButton;
3432 set {
3433 _finishButton = value;
3437 internal void SetEnableTheming() {
3438 this.EnableTheming = _owner.EnableTheming;
3441 // Renders the inner control only
3442 protected internal override void Render(HtmlTextWriter writer) {
3443 RenderContents(writer);
3447 private class FinishNavigationTemplateContainer : BaseNavigationTemplateContainer {
3448 private IButtonControl _previousButton;
3450 internal FinishNavigationTemplateContainer(Wizard owner)
3451 : base(owner) {
3454 internal override IButtonControl PreviousButton {
3455 get {
3456 if (_previousButton != null) {
3457 return _previousButton;
3460 _previousButton = FindControl(Wizard.FinishPreviousButtonID) as IButtonControl;
3461 return _previousButton;
3464 set {
3465 _previousButton = value;
3470 private class StartNavigationTemplateContainer : BaseNavigationTemplateContainer {
3471 private IButtonControl _nextButton;
3473 internal StartNavigationTemplateContainer(Wizard owner)
3474 : base(owner) {
3477 internal override IButtonControl NextButton {
3478 get {
3479 if (_nextButton != null) {
3480 return _nextButton;
3483 _nextButton = FindControl(Wizard.StartNextButtonID) as IButtonControl;
3485 return _nextButton;
3488 set {
3489 _nextButton = value;
3494 private class StepNavigationTemplateContainer : BaseNavigationTemplateContainer {
3496 internal StepNavigationTemplateContainer(Wizard owner)
3497 : base(owner) {
3501 #endregion
3504 public sealed class WizardStepCollection : IList {
3505 private Wizard _wizard;
3508 internal WizardStepCollection(Wizard wizard) {
3509 this._wizard = wizard;
3510 wizard.TemplatedSteps.Clear();
3514 public int Count {
3515 get {
3516 return Views.Count;
3521 public bool IsReadOnly {
3522 get {
3523 return Views.IsReadOnly;
3528 public bool IsSynchronized {
3529 get {
3530 return false;
3535 public object SyncRoot {
3536 get {
3537 return this;
3541 private ViewCollection Views {
3542 get {
3543 return _wizard.MultiView.Views;
3548 public WizardStepBase this[int index] {
3549 get {
3550 return (WizardStepBase)Views[index];
3555 public void Add(WizardStepBase wizardStep) {
3557 if (wizardStep == null) {
3558 throw new ArgumentNullException("wizardStep");
3561 wizardStep.PreventAutoID();
3562 RemoveIfAlreadyExistsInWizard(wizardStep);
3564 wizardStep.Owner = _wizard;
3565 Views.Add(wizardStep);
3566 AddTemplatedWizardStep(wizardStep);
3568 NotifyWizardStepsChanged();
3572 public void AddAt(int index, WizardStepBase wizardStep) {
3573 if (wizardStep == null) {
3574 throw new ArgumentNullException("wizardStep");
3577 RemoveIfAlreadyExistsInWizard(wizardStep);
3579 wizardStep.PreventAutoID();
3580 wizardStep.Owner = _wizard;
3581 Views.AddAt(index, wizardStep);
3582 AddTemplatedWizardStep(wizardStep);
3584 NotifyWizardStepsChanged();
3588 private void AddTemplatedWizardStep(WizardStepBase wizardStep) {
3589 var templatedWizardStep = wizardStep as TemplatedWizardStep;
3590 if (templatedWizardStep != null) {
3591 _wizard.TemplatedSteps.Add(templatedWizardStep);
3592 _wizard.RegisterCustomNavigationContainers(templatedWizardStep);
3597 public void Clear() {
3598 Views.Clear();
3599 _wizard.TemplatedSteps.Clear();
3601 NotifyWizardStepsChanged();
3605 public bool Contains(WizardStepBase wizardStep) {
3606 if (wizardStep == null) {
3607 throw new ArgumentNullException("wizardStep");
3610 return Views.Contains(wizardStep);
3614 public void CopyTo(WizardStepBase[] array, int index) {
3615 Views.CopyTo(array, index);
3619 public IEnumerator GetEnumerator() {
3620 return Views.GetEnumerator();
3624 public int IndexOf(WizardStepBase wizardStep) {
3625 if (wizardStep == null) {
3626 throw new ArgumentNullException("wizardStep");
3629 return Views.IndexOf(wizardStep);
3633 public void Insert(int index, WizardStepBase wizardStep) {
3634 AddAt(index, wizardStep);
3637 internal void NotifyWizardStepsChanged() {
3638 _wizard.OnWizardStepsChanged();
3642 public void Remove(WizardStepBase wizardStep) {
3643 if (wizardStep == null) {
3644 throw new ArgumentNullException("wizardStep");
3647 Views.Remove(wizardStep);
3648 wizardStep.Owner = null;
3649 var templatedWizardStep = wizardStep as TemplatedWizardStep;
3650 if (templatedWizardStep != null) {
3651 _wizard.TemplatedSteps.Remove(templatedWizardStep);
3654 NotifyWizardStepsChanged();
3658 public void RemoveAt(int index) {
3659 WizardStepBase wizardStep = Views[index] as WizardStepBase;
3660 if (wizardStep != null) {
3661 wizardStep.Owner = null;
3662 var templatedWizardStep = wizardStep as TemplatedWizardStep;
3663 if (templatedWizardStep != null) {
3664 _wizard.TemplatedSteps.Remove(templatedWizardStep);
3667 Views.RemoveAt(index);
3669 NotifyWizardStepsChanged();
3672 private static void RemoveIfAlreadyExistsInWizard(WizardStepBase wizardStep) {
3673 if (wizardStep.Owner != null) {
3674 wizardStep.Owner.WizardSteps.Remove(wizardStep);
3678 private static WizardStepBase GetStepAndVerify(object value) {
3679 WizardStepBase step = value as WizardStepBase;
3680 if (step == null)
3681 throw new ArgumentException(SR.GetString(SR.Wizard_WizardStepOnly));
3683 return step;
3686 #region ICollection implementation
3689 /// <internalonly/>
3690 void ICollection.CopyTo(Array array, int index) {
3691 Views.CopyTo(array, index);
3693 #endregion //ICollection implementation
3695 #region IList implementation
3698 /// <internalonly/>
3699 bool IList.IsFixedSize {
3700 get {
3701 return false;
3706 /// <internalonly/>
3707 object IList.this[int index] {
3708 get {
3709 return Views[index];
3711 set {
3712 RemoveAt(index);
3713 AddAt(index, GetStepAndVerify(value));
3718 /// <internalonly/>
3719 int IList.Add(object value) {
3720 WizardStepBase step = GetStepAndVerify(value);
3721 step.PreventAutoID();
3722 Add(step);
3723 return IndexOf(step);
3727 /// <internalonly/>
3728 bool IList.Contains(object value) {
3729 return Contains(GetStepAndVerify(value));
3733 /// <internalonly/>
3734 int IList.IndexOf(object value) {
3735 return IndexOf(GetStepAndVerify(value));
3739 /// <internalonly/>
3740 void IList.Insert(int index, object value) {
3741 AddAt(index, GetStepAndVerify(value));
3745 /// <internalonly/>
3746 void IList.Remove(object value) {
3747 Remove(GetStepAndVerify(value));
3749 #endregion // IList implementation
3752 [SupportsEventValidation]
3753 internal class WizardDefaultInnerTable : Table {
3754 internal WizardDefaultInnerTable() {
3755 PreventAutoID();
3757 // cell padding and spacing should be 0 since these tables are for internal layout only.
3758 CellPadding = 0;
3759 CellSpacing = 0;
3764 public class WizardNavigationEventArgs : EventArgs {
3766 private int _currentStepIndex;
3767 private int _nextStepIndex;
3768 private bool _cancel;
3771 public WizardNavigationEventArgs(int currentStepIndex, int nextStepIndex) {
3772 _currentStepIndex = currentStepIndex;
3773 _nextStepIndex = nextStepIndex;
3777 public bool Cancel {
3778 get {
3779 return _cancel;
3781 set {
3782 _cancel = value;
3787 public int CurrentStepIndex {
3788 get {
3789 return _currentStepIndex;
3794 public int NextStepIndex {
3795 get {
3796 return _nextStepIndex;
3800 internal void SetNextStepIndex(int nextStepIndex) {
3801 _nextStepIndex = nextStepIndex;
3806 public delegate void WizardNavigationEventHandler(object sender, WizardNavigationEventArgs e);