1 //------------------------------------------------------------------------------
2 // <copyright file="Wizard.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System
.Web
.UI
.WebControls
{
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
;
16 using System
.Security
.Permissions
;
19 using System
.Web
.Util
;
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();
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;
115 : this(_displaySideBarDefaultValue
) {
119 internal Wizard(bool displaySideBarDefault
) {
120 _displaySideBarDefault
= displaySideBarDefault
;
121 _displaySideBar
= displaySideBarDefault
;
124 #region Public Properties
128 DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
),
129 WebSysDescription(SR
.Wizard_ActiveStep
)
131 public WizardStepBase ActiveStep
{
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
;
145 WebCategory("Behavior"),
146 WebSysDescription(SR
.Wizard_ActiveStepIndex
),
148 public virtual int ActiveStepIndex
{
150 return MultiView
.ActiveViewIndex
;
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();
176 /// Gets or sets the URL of an image to be displayed for the cancel button.
180 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
181 WebCategory("Appearance"),
182 WebSysDescription(SR
.Wizard_CancelButtonImageUrl
),
185 public virtual string CancelButtonImageUrl
{
187 object obj
= ViewState
["CancelButtonImageUrl"];
188 return (obj
== null) ? String
.Empty
: (string)obj
;
191 ViewState
["CancelButtonImageUrl"] = value;
197 /// Gets the style of the cancel buttons.
200 WebCategory("Styles"),
202 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
203 NotifyParentProperty(true),
204 PersistenceMode(PersistenceMode
.InnerProperty
),
205 WebSysDescription(SR
.Wizard_CancelButtonStyle
)
207 public Style CancelButtonStyle
{
209 if (_cancelButtonStyle
== null) {
210 _cancelButtonStyle
= new Style();
211 if (IsTrackingViewState
) {
212 ((IStateManager
)_cancelButtonStyle
).TrackViewState();
215 return _cancelButtonStyle
;
222 WebCategory("Appearance"),
223 WebSysDefaultValue(SR
.Wizard_Default_CancelButtonText
),
224 WebSysDescription(SR
.Wizard_CancelButtonText
)
226 public virtual String CancelButtonText
{
228 string s
= ViewState
["CancelButtonText"] as String
;
229 return s
== null ? SR
.GetString(SR
.Wizard_Default_CancelButtonText
) : s
;
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
{
246 object obj
= ViewState
["CancelButtonType"];
247 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
250 ValidateButtonType(value);
251 ViewState
["CancelButtonType"] = value;
258 Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
260 WebCategory("Behavior"),
261 WebSysDescription(SR
.Wizard_CancelDestinationPageUrl
),
264 public virtual String CancelDestinationPageUrl
{
266 string s
= ViewState
["CancelDestinationPageUrl"] as String
;
267 return s
== null ? String
.Empty
: s
;
270 ViewState
["CancelDestinationPageUrl"] = value;
276 WebCategory("Layout"),
278 WebSysDescription(SR
.Wizard_CellPadding
)
280 public virtual int CellPadding
{
282 if (ControlStyleCreated
== false) {
285 return ((TableStyle
)ControlStyle
).CellPadding
;
288 ((TableStyle
)ControlStyle
).CellPadding
= value;
294 WebCategory("Layout"),
296 WebSysDescription(SR
.Wizard_CellSpacing
)
298 public virtual int CellSpacing
{
300 if (ControlStyleCreated
== false) {
303 return ((TableStyle
)ControlStyle
).CellSpacing
;
306 ((TableStyle
)ControlStyle
).CellSpacing
= value;
314 WebCategory("Behavior"),
315 WebSysDescription(SR
.Wizard_DisplayCancelButton
),
317 public virtual bool DisplayCancelButton
{
319 object o
= ViewState
["DisplayCancelButton"];
320 return o
== null ? false : (bool)o
;
323 ViewState
["DisplayCancelButton"] = value;
331 WebCategory("Behavior"),
332 WebSysDescription(SR
.Wizard_DisplaySideBar
),
334 public virtual bool DisplaySideBar
{
336 return _displaySideBar
;
339 if (value != _displaySideBar
) {
340 _displaySideBar
= value;
341 _sideBarTableCell
= null;
342 RequiresControlsRecreation();
349 /// Gets or sets the URL of an image to be displayed for the finish button.
353 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
354 WebCategory("Appearance"),
355 WebSysDescription(SR
.Wizard_FinishCompleteButtonImageUrl
),
358 public virtual string FinishCompleteButtonImageUrl
{
360 object obj
= ViewState
["FinishCompleteButtonImageUrl"];
361 return (obj
== null) ? String
.Empty
: (string)obj
;
364 ViewState
["FinishCompleteButtonImageUrl"] = value;
370 /// Gets the style of the finishStep buttons.
373 WebCategory("Styles"),
375 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
376 NotifyParentProperty(true),
377 PersistenceMode(PersistenceMode
.InnerProperty
),
378 WebSysDescription(SR
.Wizard_FinishCompleteButtonStyle
)
380 public Style FinishCompleteButtonStyle
{
382 if (_finishCompleteButtonStyle
== null) {
383 _finishCompleteButtonStyle
= new Style();
384 if (IsTrackingViewState
) {
385 ((IStateManager
)_finishCompleteButtonStyle
).TrackViewState();
388 return _finishCompleteButtonStyle
;
395 WebCategory("Appearance"),
396 WebSysDefaultValue(SR
.Wizard_Default_FinishButtonText
),
397 WebSysDescription(SR
.Wizard_FinishCompleteButtonText
)
399 public virtual String FinishCompleteButtonText
{
401 string s
= ViewState
["FinishCompleteButtonText"] as String
;
402 return s
== null ? SR
.GetString(SR
.Wizard_Default_FinishButtonText
) : s
;
405 ViewState
["FinishCompleteButtonText"] = value;
411 WebCategory("Appearance"),
412 DefaultValue(ButtonType
.Button
),
413 WebSysDescription(SR
.Wizard_FinishCompleteButtonType
)
415 public virtual ButtonType FinishCompleteButtonType
{
417 object obj
= ViewState
["FinishCompleteButtonType"];
418 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
421 ValidateButtonType(value);
422 ViewState
["FinishCompleteButtonType"] = value;
428 /// Gets or sets the URL for the continue button.
432 Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
434 WebCategory("Behavior"),
435 WebSysDescription(SR
.Wizard_FinishDestinationPageUrl
),
438 public virtual string FinishDestinationPageUrl
{
440 object obj
= ViewState
["FinishDestinationPageUrl"];
441 return (obj
== null) ? String
.Empty
: (string)obj
;
444 ViewState
["FinishDestinationPageUrl"] = value;
450 /// Gets or sets the URL of an image to be displayed for the finish step's previous button.
454 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
455 WebCategory("Appearance"),
456 WebSysDescription(SR
.Wizard_FinishPreviousButtonImageUrl
),
459 public virtual string FinishPreviousButtonImageUrl
{
461 object obj
= ViewState
["FinishPreviousButtonImageUrl"];
462 return (obj
== null) ? String
.Empty
: (string)obj
;
465 ViewState
["FinishPreviousButtonImageUrl"] = value;
471 /// Gets the style of the navigation buttons.
474 WebCategory("Styles"),
476 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
477 NotifyParentProperty(true),
478 PersistenceMode(PersistenceMode
.InnerProperty
),
479 WebSysDescription(SR
.Wizard_FinishPreviousButtonStyle
)
481 public Style FinishPreviousButtonStyle
{
483 if (_finishPreviousButtonStyle
== null) {
484 _finishPreviousButtonStyle
= new Style();
485 if (IsTrackingViewState
) {
486 ((IStateManager
)_finishPreviousButtonStyle
).TrackViewState();
489 return _finishPreviousButtonStyle
;
496 WebCategory("Appearance"),
497 WebSysDefaultValue(SR
.Wizard_Default_StepPreviousButtonText
),
498 WebSysDescription(SR
.Wizard_FinishPreviousButtonText
)
500 public virtual String FinishPreviousButtonText
{
502 string s
= ViewState
["FinishPreviousButtonText"] as String
;
503 return s
== null ? SR
.GetString(SR
.Wizard_Default_StepPreviousButtonText
) : s
;
506 ViewState
["FinishPreviousButtonText"] = value;
512 WebCategory("Appearance"),
513 DefaultValue(ButtonType
.Button
),
514 WebSysDescription(SR
.Wizard_FinishPreviousButtonType
)
516 public virtual ButtonType FinishPreviousButtonType
{
518 object obj
= ViewState
["FinishPreviousButtonType"];
519 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
522 ValidateButtonType(value);
523 ViewState
["FinishPreviousButtonType"] = value;
531 PersistenceMode(PersistenceMode
.InnerProperty
),
532 TemplateContainer(typeof(Wizard
)),
533 WebSysDescription(SR
.Wizard_FinishNavigationTemplate
)
535 public virtual ITemplate FinishNavigationTemplate
{
537 return _finishNavigationTemplate
;
540 _finishNavigationTemplate
= value;
541 RequiresControlsRecreation();
547 WebCategory("Styles"),
549 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
550 NotifyParentProperty(true),
551 PersistenceMode(PersistenceMode
.InnerProperty
),
552 WebSysDescription(SR
.WebControl_HeaderStyle
)
554 public TableItemStyle HeaderStyle
{
556 if (_headerStyle
== null) {
557 _headerStyle
= new TableItemStyle();
558 if (IsTrackingViewState
)
559 ((IStateManager
)_headerStyle
).TrackViewState();
569 PersistenceMode(PersistenceMode
.InnerProperty
),
570 TemplateContainer(typeof(Wizard
)),
571 WebSysDescription(SR
.WebControl_HeaderTemplate
)
573 public virtual ITemplate HeaderTemplate
{
575 return _headerTemplate
;
578 _headerTemplate
= value;
579 RequiresControlsRecreation();
587 WebCategory("Appearance"),
588 WebSysDescription(SR
.Wizard_HeaderText
)
590 public virtual string HeaderText
{
592 string s
= ViewState
["HeaderText"] as String
;
593 return s
== null ? String
.Empty
: s
;
596 ViewState
["HeaderText"] = value;
604 PersistenceMode(PersistenceMode
.InnerProperty
),
605 TemplateContainer(typeof(Wizard
)),
606 WebSysDescription(SR
.Wizard_LayoutTemplate
)
608 public virtual ITemplate LayoutTemplate
{
610 return _layoutTemplate
;
613 _layoutTemplate
= value;
614 RequiresControlsRecreation();
620 /// Gets the style of the navigation buttons.
623 WebCategory("Styles"),
625 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
626 NotifyParentProperty(true),
627 PersistenceMode(PersistenceMode
.InnerProperty
),
628 WebSysDescription(SR
.Wizard_NavigationButtonStyle
)
630 public Style NavigationButtonStyle
{
632 if (_navigationButtonStyle
== null) {
633 _navigationButtonStyle
= new Style();
634 if (IsTrackingViewState
) {
635 ((IStateManager
)_navigationButtonStyle
).TrackViewState();
638 return _navigationButtonStyle
;
644 WebCategory("Styles"),
646 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
647 NotifyParentProperty(true),
648 PersistenceMode(PersistenceMode
.InnerProperty
),
649 WebSysDescription(SR
.Wizard_NavigationStyle
)
651 public TableItemStyle NavigationStyle
{
653 if (_navigationStyle
== null) {
654 _navigationStyle
= new TableItemStyle();
655 if (IsTrackingViewState
)
656 ((IStateManager
)_navigationStyle
).TrackViewState();
658 return _navigationStyle
;
664 /// Gets or sets the URL of an image to be displayed for the finish step's previous button.
668 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
669 WebCategory("Appearance"),
670 WebSysDescription(SR
.Wizard_StartNextButtonImageUrl
),
673 public virtual string StartNextButtonImageUrl
{
675 object obj
= ViewState
["StartNextButtonImageUrl"];
676 return (obj
== null) ? String
.Empty
: (string)obj
;
679 ViewState
["StartNextButtonImageUrl"] = value;
685 /// Gets the style of the navigation buttons.
688 WebCategory("Styles"),
690 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
691 NotifyParentProperty(true),
692 PersistenceMode(PersistenceMode
.InnerProperty
),
693 WebSysDescription(SR
.Wizard_StartNextButtonStyle
)
695 public Style StartNextButtonStyle
{
697 if (_startNextButtonStyle
== null) {
698 _startNextButtonStyle
= new Style();
699 if (IsTrackingViewState
) {
700 ((IStateManager
)_startNextButtonStyle
).TrackViewState();
703 return _startNextButtonStyle
;
710 WebCategory("Appearance"),
711 WebSysDefaultValue(SR
.Wizard_Default_StepNextButtonText
),
712 WebSysDescription(SR
.Wizard_StartNextButtonText
)
714 public virtual String StartNextButtonText
{
716 string s
= ViewState
["StartNextButtonText"] as String
;
717 return s
== null ? SR
.GetString(SR
.Wizard_Default_StepNextButtonText
) : s
;
720 ViewState
["StartNextButtonText"] = value;
726 WebCategory("Appearance"),
727 DefaultValue(ButtonType
.Button
),
728 WebSysDescription(SR
.Wizard_StartNextButtonType
)
730 public virtual ButtonType StartNextButtonType
{
732 object obj
= ViewState
["StartNextButtonType"];
733 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
736 ValidateButtonType(value);
737 ViewState
["StartNextButtonType"] = value;
743 /// Gets or sets the URL of an image to be displayed for the next button.
747 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
748 WebCategory("Appearance"),
749 WebSysDescription(SR
.Wizard_StepNextButtonImageUrl
),
752 public virtual string StepNextButtonImageUrl
{
754 object obj
= ViewState
["StepNextButtonImageUrl"];
755 return (obj
== null) ? String
.Empty
: (string)obj
;
758 ViewState
["StepNextButtonImageUrl"] = value;
764 /// Gets the style of the navigation buttons.
767 WebCategory("Styles"),
769 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
770 NotifyParentProperty(true),
771 PersistenceMode(PersistenceMode
.InnerProperty
),
772 WebSysDescription(SR
.Wizard_StepNextButtonStyle
)
774 public Style StepNextButtonStyle
{
776 if (_stepNextButtonStyle
== null) {
777 _stepNextButtonStyle
= new Style();
778 if (IsTrackingViewState
) {
779 ((IStateManager
)_stepNextButtonStyle
).TrackViewState();
782 return _stepNextButtonStyle
;
789 WebCategory("Appearance"),
790 WebSysDefaultValue(SR
.Wizard_Default_StepNextButtonText
),
791 WebSysDescription(SR
.Wizard_StepNextButtonText
)
793 public virtual String StepNextButtonText
{
795 string s
= ViewState
["StepNextButtonText"] as String
;
796 return s
== null ? SR
.GetString(SR
.Wizard_Default_StepNextButtonText
) : s
;
799 ViewState
["StepNextButtonText"] = value;
805 WebCategory("Appearance"),
806 DefaultValue(ButtonType
.Button
),
807 WebSysDescription(SR
.Wizard_StepNextButtonType
)
809 public virtual ButtonType StepNextButtonType
{
811 object obj
= ViewState
["StepNextButtonType"];
812 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
815 ValidateButtonType(value);
816 ViewState
["StepNextButtonType"] = value;
822 /// Gets or sets the URL of an image to be displayed for the previous button.
826 Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
827 WebCategory("Appearance"),
828 WebSysDescription(SR
.Wizard_StepPreviousButtonImageUrl
),
831 public virtual string StepPreviousButtonImageUrl
{
833 object obj
= ViewState
["StepPreviousButtonImageUrl"];
834 return (obj
== null) ? String
.Empty
: (string)obj
;
837 ViewState
["StepPreviousButtonImageUrl"] = value;
843 /// Gets the style of the navigation buttons.
846 WebCategory("Styles"),
848 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
849 NotifyParentProperty(true),
850 PersistenceMode(PersistenceMode
.InnerProperty
),
851 WebSysDescription(SR
.Wizard_StepPreviousButtonStyle
)
853 public Style StepPreviousButtonStyle
{
855 if (_stepPreviousButtonStyle
== null) {
856 _stepPreviousButtonStyle
= new Style();
857 if (IsTrackingViewState
) {
858 ((IStateManager
)_stepPreviousButtonStyle
).TrackViewState();
861 return _stepPreviousButtonStyle
;
868 WebCategory("Appearance"),
869 WebSysDefaultValue(SR
.Wizard_Default_StepPreviousButtonText
),
870 WebSysDescription(SR
.Wizard_StepPreviousButtonText
)
872 public virtual String StepPreviousButtonText
{
874 string s
= ViewState
["StepPreviousButtonText"] as String
;
875 return s
== null ? SR
.GetString(SR
.Wizard_Default_StepPreviousButtonText
) : s
;
878 ViewState
["StepPreviousButtonText"] = value;
884 WebCategory("Appearance"),
885 DefaultValue(ButtonType
.Button
),
886 WebSysDescription(SR
.Wizard_StepPreviousButtonType
)
888 public virtual ButtonType StepPreviousButtonType
{
890 object obj
= ViewState
["StepPreviousButtonType"];
891 return (obj
== null) ? ButtonType
.Button
: (ButtonType
)obj
;
894 ValidateButtonType(value);
895 ViewState
["StepPreviousButtonType"] = value;
901 /// Gets the style of the side bar buttons.
904 WebCategory("Styles"),
906 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
907 NotifyParentProperty(true),
908 PersistenceMode(PersistenceMode
.InnerProperty
),
909 WebSysDescription(SR
.Wizard_SideBarButtonStyle
)
911 public Style SideBarButtonStyle
{
913 if (_sideBarButtonStyle
== null) {
914 _sideBarButtonStyle
= new Style();
915 if (IsTrackingViewState
) {
916 ((IStateManager
)_sideBarButtonStyle
).TrackViewState();
919 return _sideBarButtonStyle
;
925 WebCategory("Styles"),
927 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
928 NotifyParentProperty(true),
929 PersistenceMode(PersistenceMode
.InnerProperty
),
930 WebSysDescription(SR
.Wizard_SideBarStyle
)
932 public TableItemStyle SideBarStyle
{
934 if (_sideBarStyle
== null) {
935 _sideBarStyle
= new TableItemStyle();
936 if (IsTrackingViewState
)
937 ((IStateManager
)_sideBarStyle
).TrackViewState();
939 return _sideBarStyle
;
947 PersistenceMode(PersistenceMode
.InnerProperty
),
948 TemplateContainer(typeof(Wizard
)),
949 WebSysDescription(SR
.Wizard_SideBarTemplate
)
951 public virtual ITemplate SideBarTemplate
{
953 return _sideBarTemplate
;
956 _sideBarTemplate
= value;
957 _sideBarTableCell
= null;
958 RequiresControlsRecreation();
965 WebCategory("Appearance"),
966 WebSysDefaultValue(SR
.Wizard_Default_SkipToContentText
),
967 WebSysDescription(SR
.WebControl_SkipLinkText
)
969 public virtual String SkipLinkText
{
971 string s
= SkipLinkTextInternal
;
972 return s
== null ? SR
.GetString(SR
.Wizard_Default_SkipToContentText
) : s
;
975 ViewState
["SkipLinkText"] = value;
983 PersistenceMode(PersistenceMode
.InnerProperty
),
984 TemplateContainer(typeof(Wizard
)),
985 WebSysDescription(SR
.Wizard_StartNavigationTemplate
)
987 public virtual ITemplate StartNavigationTemplate
{
989 return _startNavigationTemplate
;
992 _startNavigationTemplate
= value;
993 RequiresControlsRecreation();
1001 PersistenceMode(PersistenceMode
.InnerProperty
),
1002 TemplateContainer(typeof(Wizard
)),
1003 WebSysDescription(SR
.Wizard_StepNavigationTemplate
)
1005 public virtual ITemplate StepNavigationTemplate
{
1007 return _stepNavigationTemplate
;
1010 _stepNavigationTemplate
= value;
1011 RequiresControlsRecreation();
1018 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
1019 NotifyParentProperty(true),
1020 PersistenceMode(PersistenceMode
.InnerProperty
),
1021 WebCategory("Styles"),
1022 WebSysDescription(SR
.Wizard_StepStyle
)
1024 public TableItemStyle StepStyle
{
1026 if (_stepStyle
== null) {
1027 _stepStyle
= new TableItemStyle();
1028 if (IsTrackingViewState
)
1029 ((IStateManager
)_stepStyle
).TrackViewState();
1037 protected override HtmlTextWriterTag TagKey
{
1039 return HtmlTextWriterTag
.Table
;
1045 DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
),
1046 Editor("System.Web.UI.Design.WebControls.WizardStepCollectionEditor," + AssemblyRef
.SystemDesign
, typeof(UITypeEditor
)),
1047 PersistenceMode(PersistenceMode
.InnerProperty
),
1049 WebSysDescription(SR
.Wizard_WizardSteps
),
1051 public virtual WizardStepCollection WizardSteps
{
1053 if (_wizardStepCollection
== null) {
1054 _wizardStepCollection
= new WizardStepCollection(this);
1057 return _wizardStepCollection
;
1063 #region Public Events
1066 WebCategory("Action"),
1067 WebSysDescription(SR
.Wizard_ActiveStepChanged
)
1069 public event EventHandler ActiveStepChanged
{
1071 Events
.AddHandler(_eventActiveStepChanged
, value);
1074 Events
.RemoveHandler(_eventActiveStepChanged
, value);
1080 WebCategory("Action"),
1081 WebSysDescription(SR
.Wizard_CancelButtonClick
)
1083 public event EventHandler CancelButtonClick
{
1085 Events
.AddHandler(_eventCancelButtonClick
, value);
1089 Events
.RemoveHandler(_eventCancelButtonClick
, value);
1095 WebCategory("Action"),
1096 WebSysDescription(SR
.Wizard_FinishButtonClick
)
1098 public event WizardNavigationEventHandler FinishButtonClick
{
1100 Events
.AddHandler(_eventFinishButtonClick
, value);
1103 Events
.RemoveHandler(_eventFinishButtonClick
, value);
1109 WebCategory("Action"),
1110 WebSysDescription(SR
.Wizard_NextButtonClick
)
1112 public event WizardNavigationEventHandler NextButtonClick
{
1114 Events
.AddHandler(_eventNextButtonClick
, value);
1118 Events
.RemoveHandler(_eventNextButtonClick
, value);
1124 WebCategory("Action"),
1125 WebSysDescription(SR
.Wizard_PreviousButtonClick
)
1127 public event WizardNavigationEventHandler PreviousButtonClick
{
1129 Events
.AddHandler(_eventPreviousButtonClick
, value);
1132 Events
.RemoveHandler(_eventPreviousButtonClick
, value);
1138 WebCategory("Action"),
1139 WebSysDescription(SR
.Wizard_SideBarButtonClick
)
1141 public virtual event WizardNavigationEventHandler SideBarButtonClick
{
1143 Events
.AddHandler(_eventSideBarButtonClick
, value);
1146 Events
.RemoveHandler(_eventSideBarButtonClick
, value);
1152 #region Internal Properties
1154 internal Dictionary
<WizardStepBase
, BaseNavigationTemplateContainer
> CustomNavigationContainers
{
1156 if (_customNavigationContainers
== null) {
1157 _customNavigationContainers
= new Dictionary
<WizardStepBase
, BaseNavigationTemplateContainer
>();
1159 return _customNavigationContainers
;
1164 private ITemplate CustomNavigationTemplate
{
1166 var templatedActiveStep
= ActiveStep
as TemplatedWizardStep
;
1167 return templatedActiveStep
== null ? null : templatedActiveStep
.CustomNavigationTemplate
;
1172 private Stack
<int> History
{
1174 if (_historyStack
== null)
1175 _historyStack
= new Stack
<int>();
1177 return _historyStack
;
1181 private bool IsMacIE5
{
1183 if (!_isMacIE
.HasValue
&& !DesignMode
) {
1184 HttpBrowserCapabilities browser
= null;
1186 browser
= Page
.Request
.Browser
;
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
{
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();
1218 internal virtual bool ShowCustomNavigationTemplate
{
1220 return CustomNavigationTemplate
!= null;
1225 internal bool ShouldRenderChildControl
{
1231 if (_designModeState
== null) {
1235 object o
= _designModeState
["ShouldRenderWizardSteps"];
1236 return o
== null ? true : (bool)o
;
1241 private IWizardSideBarListControl SideBarList
{
1242 get { return _sideBarList; }
1246 private bool SideBarEnabled
{
1248 return _sideBarList
!= null && DisplaySideBar
;
1253 internal string SkipLinkTextInternal
{
1255 return ViewState
["SkipLinkText"] as String
;
1260 internal List
<TemplatedWizardStep
> TemplatedSteps
{
1262 if (_templatedSteps
== null) {
1263 _templatedSteps
= new List
<TemplatedWizardStep
>();
1265 return _templatedSteps
;
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) {
1288 /// <internalonly />
1289 protected internal override void CreateChildControls() {
1290 using (new WizardControlCollectionModifier(this)) {
1292 _customNavigationContainers
= null;
1295 if (LayoutTemplate
== null) {
1296 _rendering
= CreateTableRendering();
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);
1345 /// <para>A protected method. Creates a table control style.</para>
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
;
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();
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
) {
1398 IButtonControl button
= dataListItem
.FindControl(SideBarButtonID
) as IButtonControl
;
1399 if (button
== null) {
1401 throw new InvalidOperationException(
1402 SR
.GetString(SR
.Wizard_SideBar_Button_Not_Found
, DataListID
, SideBarButtonID
));
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
;
1423 // Render wizardstep title on the button control.
1424 WizardStepBase step
= dataListItem
.DataItem
as WizardStepBase
;
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
;
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
)) {
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
) {
1470 _activeStepIndexSet
= false;
1471 OnSideBarButtonClick(args
);
1474 // Honor user's change if activeStepIndex is set explicitely;
1475 if (!_activeStepIndexSet
) {
1476 if (AllowNavigationToStep(newIndex
)) {
1477 ActiveStepIndex
= newIndex
;
1481 // revert active step if it's cancelled.
1482 ActiveStepIndex
= oldIndex
;
1486 internal static string GetCustomContainerID(int index
) {
1487 return _customNavigationContainerIdPrefix
+ index
;
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.
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
;
1530 ActiveStepIndex
= oldIndex
;
1537 public ICollection
GetHistory() {
1538 ArrayList list
= new ArrayList();
1539 foreach (int index
in History
) {
1540 list
.Add(WizardSteps
[index
]);
1545 internal int GetPreviousStepIndex(bool popStack
) {
1546 int previousIndex
= -1;
1547 int index
= ActiveStepIndex
;
1549 if (_historyStack
== null || _historyStack
.Count
== 0) {
1550 return previousIndex
;
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();
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
) {
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
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
;
1618 /// Instantiates all the content templates for each TemplatedWizardStep
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
);
1640 /// <para>Loads the control state.</para>
1642 protected internal override void LoadControlState(object state
) {
1643 Triplet t
= state
as Triplet
;
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);
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
);
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
;
1738 if (String
.Equals(CancelCommandName
, ce
.CommandName
, StringComparison
.OrdinalIgnoreCase
)) {
1739 OnCancelButtonClick(EventArgs
.Empty
);
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;
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
) {
1766 bool previousButtonCommand
= false;
1767 _activeStepIndexSet
= false;
1769 if (String
.Equals(MoveNextCommandName
, ce
.CommandName
, StringComparison
.OrdinalIgnoreCase
)) {
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
);
1782 } else if (String
.Equals(MovePreviousCommandName
, ce
.CommandName
, StringComparison
.OrdinalIgnoreCase
)) {
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
);
1798 } else if (String
.Equals(MoveCompleteCommandName
, ce
.CommandName
, StringComparison
.OrdinalIgnoreCase
)) {
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
);
1811 } else if (String
.Equals(MoveToCommandName
, ce
.CommandName
, StringComparison
.OrdinalIgnoreCase
)) {
1812 newIndex
= Int32
.Parse((String
)ce
.CommandArgument
, CultureInfo
.InvariantCulture
);
1813 args
.SetNextStepIndex(newIndex
);
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
;
1832 // revert active step if it's cancelled.
1833 ActiveStepIndex
= oldIndex
;
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
;
1854 protected virtual void OnCancelButtonClick(EventArgs e
) {
1855 EventHandler handler
= (EventHandler
)Events
[_eventCancelButtonClick
];
1856 if (handler
!= null) {
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
) {
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();
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;
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.
1943 Page
.VerifyRenderingInServerForm(this);
1946 EnsureChildControls();
1947 ApplyControlProperties();
1949 // Nothing to do if the Wizard is empty;
1950 if (ActiveStepIndex
== -1 || WizardSteps
.Count
== 0) {
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
);
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) {
2011 // More performant to return null than an array of null values
2016 private void SetCancelButtonVisibility(BaseNavigationTemplateContainer container
) {
2017 // Make the parent TD invisible if possible.
2018 Control c
= container
.CancelButton
as Control
;
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
) {
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) {
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) {
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
;
2180 if (Owner
.FinishNavigationTemplate
== null) {
2181 ctrl
.Parent
.Visible
= false;
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) {
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) {
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) {
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();
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) {
2314 ImageButton imageButton
= button
as ImageButton
;
2315 if (imageButton
!= null) {
2316 imageButton
.ImageUrl
= imageUrl
;
2317 imageButton
.AlternateText
= text
;
2318 imageButton
.Visible
= imageButtonVisible
;
2324 public abstract void OnlyShowCompleteStep();
2326 protected void ApplyCustomNavigationTemplateProperties() {
2327 // Make all custom navigation containers invisible
2328 foreach (BaseNavigationTemplateContainer c
in Owner
.CustomNavigationContainers
.Values
) {
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
);
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
));
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
;
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
;
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
;
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
)
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
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
));
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.
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
);
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
)
2615 // Returns the cell which the navigation template container should be added to
2616 private TableCell NavigationTableCell
{
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)) {
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
);
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
2714 if ((Owner
.HeaderTemplate
== null) && String
.IsNullOrEmpty(Owner
.HeaderText
)) {
2715 _headerTableRow
.Visible
= false;
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.
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
;
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();
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
) {
2812 if (Owner
.HeaderTemplate
!= null) {
2813 _headerTableCell
.EnableTheming
= Owner
.EnableTheming
;
2814 Owner
.HeaderTemplate
.InstantiateIn(_headerTableCell
);
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() {
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();
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
;
2919 private class WizardControlCollection
: ControlCollection
{
2920 public WizardControlCollection(Wizard wizard
)
2922 if (!wizard
.DesignMode
)
2923 SetCollectionReadOnly(SR
.Wizard_Cannot_Modify_ControlCollection
);
2927 private class WizardControlCollectionModifier
: IDisposable
{
2929 ControlCollection _controls
;
2930 String _originalError
;
2932 public WizardControlCollectionModifier(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
) {
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
) {
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
{
3104 ButtonType buttonType
= ButtonType
.Button
;
3105 switch (_templateType
) {
3106 case WizardTemplateType
.StartNavigationTemplate
:
3107 Debug
.Fail("Invalid template/button type");
3110 case WizardTemplateType
.StepNavigationTemplate
:
3111 buttonType
= _wizard
.StepPreviousButtonType
;
3114 case WizardTemplateType
.FinishNavigationTemplate
:
3116 buttonType
= _wizard
.FinishPreviousButtonType
;
3120 return GetButtonBasedOnType(0, buttonType
);
3124 internal IButtonControl SecondButton
{
3126 ButtonType buttonType
= ButtonType
.Button
;
3127 switch (_templateType
) {
3128 case WizardTemplateType
.StartNavigationTemplate
:
3129 buttonType
= _wizard
.StartNextButtonType
;
3132 case WizardTemplateType
.StepNavigationTemplate
:
3133 buttonType
= _wizard
.StepNextButtonType
;
3136 case WizardTemplateType
.FinishNavigationTemplate
:
3138 buttonType
= _wizard
.FinishCompleteButtonType
;
3142 return GetButtonBasedOnType(1, buttonType
);
3146 internal IButtonControl CancelButton
{
3148 ButtonType buttonType
= _wizard
.CancelButtonType
;
3149 return GetButtonBasedOnType(2, buttonType
);
3153 private IButtonControl
GetButtonBasedOnType(int pos
, ButtonType 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];
3169 private class DataListItemTemplate
: ITemplate
{
3172 internal DataListItemTemplate(Wizard 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
) {
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
;
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);
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();
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
) {
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
)
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
)
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);
3316 // remove nested table from Control tree
3321 internal void AddChildControl(Control c
) {
3322 Container
.Controls
.Add(c
);
3325 internal Control Container
{
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
) {
3345 internal Wizard 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
{
3379 if (_cancelButton
!= null) {
3380 return _cancelButton
;
3383 _cancelButton
= FindControl(Wizard
.CancelButtonID
) as IButtonControl
;
3384 return _cancelButton
;
3388 _cancelButton
= value;
3392 internal virtual IButtonControl NextButton
{
3394 if (_nextButton
!= null) {
3398 _nextButton
= FindControl(Wizard
.StepNextButtonID
) as IButtonControl
;
3403 _nextButton
= value;
3407 internal virtual IButtonControl PreviousButton
{
3409 if (_previousButton
!= null) {
3410 return _previousButton
;
3413 _previousButton
= FindControl(Wizard
.StepPreviousButtonID
) as IButtonControl
;
3414 return _previousButton
;
3418 _previousButton
= value;
3422 internal IButtonControl FinishButton
{
3424 if (_finishButton
!= null) {
3425 return _finishButton
;
3428 _finishButton
= FindControl(Wizard
.FinishButtonID
) as IButtonControl
;
3429 return _finishButton
;
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
)
3454 internal override IButtonControl PreviousButton
{
3456 if (_previousButton
!= null) {
3457 return _previousButton
;
3460 _previousButton
= FindControl(Wizard
.FinishPreviousButtonID
) as IButtonControl
;
3461 return _previousButton
;
3465 _previousButton
= value;
3470 private class StartNavigationTemplateContainer
: BaseNavigationTemplateContainer
{
3471 private IButtonControl _nextButton
;
3473 internal StartNavigationTemplateContainer(Wizard owner
)
3477 internal override IButtonControl NextButton
{
3479 if (_nextButton
!= null) {
3483 _nextButton
= FindControl(Wizard
.StartNextButtonID
) as IButtonControl
;
3489 _nextButton
= value;
3494 private class StepNavigationTemplateContainer
: BaseNavigationTemplateContainer
{
3496 internal StepNavigationTemplateContainer(Wizard owner
)
3504 public sealed class WizardStepCollection
: IList
{
3505 private Wizard _wizard
;
3508 internal WizardStepCollection(Wizard wizard
) {
3509 this._wizard
= wizard
;
3510 wizard
.TemplatedSteps
.Clear();
3521 public bool IsReadOnly
{
3523 return Views
.IsReadOnly
;
3528 public bool IsSynchronized
{
3535 public object SyncRoot
{
3541 private ViewCollection Views
{
3543 return _wizard
.MultiView
.Views
;
3548 public WizardStepBase
this[int index
] {
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() {
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
;
3681 throw new ArgumentException(SR
.GetString(SR
.Wizard_WizardStepOnly
));
3686 #region ICollection implementation
3690 void ICollection
.CopyTo(Array array
, int index
) {
3691 Views
.CopyTo(array
, index
);
3693 #endregion //ICollection implementation
3695 #region IList implementation
3699 bool IList
.IsFixedSize
{
3707 object IList
.this[int index
] {
3709 return Views
[index
];
3713 AddAt(index
, GetStepAndVerify(value));
3719 int IList
.Add(object value) {
3720 WizardStepBase step
= GetStepAndVerify(value);
3721 step
.PreventAutoID();
3723 return IndexOf(step
);
3728 bool IList
.Contains(object value) {
3729 return Contains(GetStepAndVerify(value));
3734 int IList
.IndexOf(object value) {
3735 return IndexOf(GetStepAndVerify(value));
3740 void IList
.Insert(int index
, object value) {
3741 AddAt(index
, GetStepAndVerify(value));
3746 void IList
.Remove(object value) {
3747 Remove(GetStepAndVerify(value));
3749 #endregion // IList implementation
3752 [SupportsEventValidation
]
3753 internal class WizardDefaultInnerTable
: Table
{
3754 internal WizardDefaultInnerTable() {
3757 // cell padding and spacing should be 0 since these tables are for internal layout only.
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
{
3787 public int CurrentStepIndex
{
3789 return _currentStepIndex
;
3794 public int NextStepIndex
{
3796 return _nextStepIndex
;
3800 internal void SetNextStepIndex(int nextStepIndex
) {
3801 _nextStepIndex
= nextStepIndex
;
3806 public delegate void WizardNavigationEventHandler(object sender
, WizardNavigationEventArgs e
);