|
//------------------------------------------------------------------------------
// <copyright file="Wizard.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Drawing.Design;
using System.Globalization;
using System.Linq;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.Util;
[
Bindable(false),
DefaultEvent("FinishButtonClick"),
Designer("System.Web.UI.Design.WebControls.WizardDesigner, " + AssemblyRef.SystemDesign),
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>")
]
public class Wizard : CompositeControl {
private ITemplate _finishNavigationTemplate;
private ITemplate _headerTemplate;
private ITemplate _layoutTemplate;
private ITemplate _startNavigationTemplate;
private ITemplate _stepNavigationTemplate;
private ITemplate _sideBarTemplate;
private MultiView _multiView;
private static readonly object _eventActiveStepChanged = new object();
private static readonly object _eventFinishButtonClick = new object();
private static readonly object _eventNextButtonClick = new object();
private static readonly object _eventPreviousButtonClick = new object();
private static readonly object _eventSideBarButtonClick = new object();
private static readonly object _eventCancelButtonClick = new object();
//
public static readonly string HeaderPlaceholderId = "headerPlaceholder";
public static readonly string NavigationPlaceholderId = "navigationPlaceholder";
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SideBar", Justification = "The casing has already been established in the context of Wizard")]
public static readonly string SideBarPlaceholderId = "sideBarPlaceholder";
public static readonly string WizardStepPlaceholderId = "wizardStepPlaceholder";
public static readonly string CancelCommandName = "Cancel";
public static readonly string MoveNextCommandName = "MoveNext";
public static readonly string MovePreviousCommandName = "MovePrevious";
public static readonly string MoveToCommandName = "Move";
public static readonly string MoveCompleteCommandName = "MoveComplete";
protected static readonly string CancelButtonID = "CancelButton";
protected static readonly string StartNextButtonID = "StartNextButton";
protected static readonly string StepPreviousButtonID = "StepPreviousButton";
protected static readonly string StepNextButtonID = "StepNextButton";
protected static readonly string FinishButtonID = "FinishButton";
protected static readonly string FinishPreviousButtonID = "FinishPreviousButton";
protected static readonly string CustomPreviousButtonID = "CustomPreviousButton";
protected static readonly string CustomNextButtonID = "CustomNextButton";
protected static readonly string CustomFinishButtonID = "CustomFinishButton";
protected static readonly string DataListID = "SideBarList";
protected static readonly string SideBarButtonID = "SideBarButton";
internal const string _customNavigationControls = "CustomNavigationControls";
private const string _templatedStepsID = "TemplatedWizardSteps";
private const string _multiViewID = "WizardMultiView";
private const string _customNavigationContainerIdPrefix = "__CustomNav";
private TableCell _sideBarTableCell;
private IWizardSideBarListControl _sideBarList;
private IButtonControl _commandSender;
private Dictionary<WizardStepBase, BaseNavigationTemplateContainer> _customNavigationContainers;
private IDictionary _designModeState;
private Stack<int> _historyStack;
private List<TemplatedWizardStep> _templatedSteps;
private WizardStepCollection _wizardStepCollection;
private WizardRenderingBase _rendering;
private bool _activeStepIndexSet;
private bool _displaySideBarDefault;
private bool _displaySideBar;
private bool? _isMacIE;
private bool _renderSideBarDataList;
private Style _cancelButtonStyle;
private Style _finishCompleteButtonStyle;
private Style _finishPreviousButtonStyle;
private Style _navigationButtonStyle;
private Style _sideBarButtonStyle;
private Style _startNextButtonStyle;
private Style _stepNextButtonStyle;
private Style _stepPreviousButtonStyle;
private TableItemStyle _headerStyle;
private TableItemStyle _navigationStyle;
private TableItemStyle _sideBarStyle;
private TableItemStyle _stepStyle;
private const bool _displaySideBarDefaultValue = true; /* default to true */
private const int _viewStateArrayLength = 15;
public Wizard()
: this(_displaySideBarDefaultValue) {
}
internal Wizard(bool displaySideBarDefault) {
_displaySideBarDefault = displaySideBarDefault;
_displaySideBar = displaySideBarDefault;
}
#region Public Properties
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.Wizard_ActiveStep)
]
public WizardStepBase ActiveStep {
get {
if (ActiveStepIndex < -1 || ActiveStepIndex >= WizardSteps.Count) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_ActiveStepIndex_out_of_range));
}
return MultiView.GetActiveView() as WizardStepBase;
}
}
[
DefaultValue(-1),
Themeable(false),
WebCategory("Behavior"),
WebSysDescription(SR.Wizard_ActiveStepIndex),
]
public virtual int ActiveStepIndex {
get {
return MultiView.ActiveViewIndex;
}
set {
if (value < -1 ||
(value >= WizardSteps.Count && ControlState >= ControlState.FrameworkInitialized)) {
throw new ArgumentOutOfRangeException("value",
SR.GetString(SR.Wizard_ActiveStepIndex_out_of_range));
}
if (MultiView.ActiveViewIndex != value) {
MultiView.ActiveViewIndex = value;
_activeStepIndexSet = true;
// Need to rebind the DataList control if the active step is changed.
// This is necessary since custom sidebar template might have different
// itemtemplates defined.
if (_sideBarList != null && SideBarTemplate != null) {
_sideBarList.SelectedIndex = ActiveStepIndex;
_sideBarList.DataBind();
}
}
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the cancel button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_CancelButtonImageUrl),
UrlProperty(),
]
public virtual string CancelButtonImageUrl {
get {
object obj = ViewState["CancelButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["CancelButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the cancel buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_CancelButtonStyle)
]
public Style CancelButtonStyle {
get {
if (_cancelButtonStyle == null) {
_cancelButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_cancelButtonStyle).TrackViewState();
}
}
return _cancelButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_CancelButtonText),
WebSysDescription(SR.Wizard_CancelButtonText)
]
public virtual String CancelButtonText {
get {
string s = ViewState["CancelButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_CancelButtonText) : s;
}
set {
if (value != CancelButtonText) {
ViewState["CancelButtonText"] = value;
}
}
}
[
DefaultValue(ButtonType.Button),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_CancelButtonType)
]
public virtual ButtonType CancelButtonType {
get {
object obj = ViewState["CancelButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["CancelButtonType"] = value;
}
}
[
DefaultValue(""),
Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
Themeable(false),
WebCategory("Behavior"),
WebSysDescription(SR.Wizard_CancelDestinationPageUrl),
UrlProperty(),
]
public virtual String CancelDestinationPageUrl {
get {
string s = ViewState["CancelDestinationPageUrl"] as String;
return s == null ? String.Empty : s;
}
set {
ViewState["CancelDestinationPageUrl"] = value;
}
}
[
WebCategory("Layout"),
DefaultValue(0),
WebSysDescription(SR.Wizard_CellPadding)
]
public virtual int CellPadding {
get {
if (ControlStyleCreated == false) {
return 0;
}
return ((TableStyle)ControlStyle).CellPadding;
}
set {
((TableStyle)ControlStyle).CellPadding = value;
}
}
[
WebCategory("Layout"),
DefaultValue(0),
WebSysDescription(SR.Wizard_CellSpacing)
]
public virtual int CellSpacing {
get {
if (ControlStyleCreated == false) {
return 0;
}
return ((TableStyle)ControlStyle).CellSpacing;
}
set {
((TableStyle)ControlStyle).CellSpacing = value;
}
}
[
DefaultValue(false),
Themeable(false),
WebCategory("Behavior"),
WebSysDescription(SR.Wizard_DisplayCancelButton),
]
public virtual bool DisplayCancelButton {
get {
object o = ViewState["DisplayCancelButton"];
return o == null ? false : (bool)o;
}
set {
ViewState["DisplayCancelButton"] = value;
}
}
[
DefaultValue(true),
Themeable(false),
WebCategory("Behavior"),
WebSysDescription(SR.Wizard_DisplaySideBar),
]
public virtual bool DisplaySideBar {
get {
return _displaySideBar;
}
set {
if (value != _displaySideBar) {
_displaySideBar = value;
_sideBarTableCell = null;
RequiresControlsRecreation();
}
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the finish button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_FinishCompleteButtonImageUrl),
UrlProperty(),
]
public virtual string FinishCompleteButtonImageUrl {
get {
object obj = ViewState["FinishCompleteButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["FinishCompleteButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the finishStep buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_FinishCompleteButtonStyle)
]
public Style FinishCompleteButtonStyle {
get {
if (_finishCompleteButtonStyle == null) {
_finishCompleteButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_finishCompleteButtonStyle).TrackViewState();
}
}
return _finishCompleteButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_FinishButtonText),
WebSysDescription(SR.Wizard_FinishCompleteButtonText)
]
public virtual String FinishCompleteButtonText {
get {
string s = ViewState["FinishCompleteButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_FinishButtonText) : s;
}
set {
ViewState["FinishCompleteButtonText"] = value;
}
}
[
WebCategory("Appearance"),
DefaultValue(ButtonType.Button),
WebSysDescription(SR.Wizard_FinishCompleteButtonType)
]
public virtual ButtonType FinishCompleteButtonType {
get {
object obj = ViewState["FinishCompleteButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["FinishCompleteButtonType"] = value;
}
}
/// <devdoc>
/// Gets or sets the URL for the continue button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
Themeable(false),
WebCategory("Behavior"),
WebSysDescription(SR.Wizard_FinishDestinationPageUrl),
UrlProperty(),
]
public virtual string FinishDestinationPageUrl {
get {
object obj = ViewState["FinishDestinationPageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["FinishDestinationPageUrl"] = value;
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the finish step's previous button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_FinishPreviousButtonImageUrl),
UrlProperty(),
]
public virtual string FinishPreviousButtonImageUrl {
get {
object obj = ViewState["FinishPreviousButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["FinishPreviousButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the navigation buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_FinishPreviousButtonStyle)
]
public Style FinishPreviousButtonStyle {
get {
if (_finishPreviousButtonStyle == null) {
_finishPreviousButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_finishPreviousButtonStyle).TrackViewState();
}
}
return _finishPreviousButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_StepPreviousButtonText),
WebSysDescription(SR.Wizard_FinishPreviousButtonText)
]
public virtual String FinishPreviousButtonText {
get {
string s = ViewState["FinishPreviousButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_StepPreviousButtonText) : s;
}
set {
ViewState["FinishPreviousButtonText"] = value;
}
}
[
WebCategory("Appearance"),
DefaultValue(ButtonType.Button),
WebSysDescription(SR.Wizard_FinishPreviousButtonType)
]
public virtual ButtonType FinishPreviousButtonType {
get {
object obj = ViewState["FinishPreviousButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["FinishPreviousButtonType"] = value;
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.Wizard_FinishNavigationTemplate)
]
public virtual ITemplate FinishNavigationTemplate {
get {
return _finishNavigationTemplate;
}
set {
_finishNavigationTemplate = value;
RequiresControlsRecreation();
}
}
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.WebControl_HeaderStyle)
]
public TableItemStyle HeaderStyle {
get {
if (_headerStyle == null) {
_headerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_headerStyle).TrackViewState();
}
return _headerStyle;
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.WebControl_HeaderTemplate)
]
public virtual ITemplate HeaderTemplate {
get {
return _headerTemplate;
}
set {
_headerTemplate = value;
RequiresControlsRecreation();
}
}
[
DefaultValue(""),
Localizable(true),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_HeaderText)
]
public virtual string HeaderText {
get {
string s = ViewState["HeaderText"] as String;
return s == null ? String.Empty : s;
}
set {
ViewState["HeaderText"] = value;
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.Wizard_LayoutTemplate)
]
public virtual ITemplate LayoutTemplate {
get {
return _layoutTemplate;
}
set {
_layoutTemplate = value;
RequiresControlsRecreation();
}
}
/// <devdoc>
/// Gets the style of the navigation buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_NavigationButtonStyle)
]
public Style NavigationButtonStyle {
get {
if (_navigationButtonStyle == null) {
_navigationButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_navigationButtonStyle).TrackViewState();
}
}
return _navigationButtonStyle;
}
}
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_NavigationStyle)
]
public TableItemStyle NavigationStyle {
get {
if (_navigationStyle == null) {
_navigationStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_navigationStyle).TrackViewState();
}
return _navigationStyle;
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the finish step's previous button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_StartNextButtonImageUrl),
UrlProperty(),
]
public virtual string StartNextButtonImageUrl {
get {
object obj = ViewState["StartNextButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["StartNextButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the navigation buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_StartNextButtonStyle)
]
public Style StartNextButtonStyle {
get {
if (_startNextButtonStyle == null) {
_startNextButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_startNextButtonStyle).TrackViewState();
}
}
return _startNextButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_StepNextButtonText),
WebSysDescription(SR.Wizard_StartNextButtonText)
]
public virtual String StartNextButtonText {
get {
string s = ViewState["StartNextButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_StepNextButtonText) : s;
}
set {
ViewState["StartNextButtonText"] = value;
}
}
[
WebCategory("Appearance"),
DefaultValue(ButtonType.Button),
WebSysDescription(SR.Wizard_StartNextButtonType)
]
public virtual ButtonType StartNextButtonType {
get {
object obj = ViewState["StartNextButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["StartNextButtonType"] = value;
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the next button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_StepNextButtonImageUrl),
UrlProperty(),
]
public virtual string StepNextButtonImageUrl {
get {
object obj = ViewState["StepNextButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["StepNextButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the navigation buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_StepNextButtonStyle)
]
public Style StepNextButtonStyle {
get {
if (_stepNextButtonStyle == null) {
_stepNextButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_stepNextButtonStyle).TrackViewState();
}
}
return _stepNextButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_StepNextButtonText),
WebSysDescription(SR.Wizard_StepNextButtonText)
]
public virtual String StepNextButtonText {
get {
string s = ViewState["StepNextButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_StepNextButtonText) : s;
}
set {
ViewState["StepNextButtonText"] = value;
}
}
[
WebCategory("Appearance"),
DefaultValue(ButtonType.Button),
WebSysDescription(SR.Wizard_StepNextButtonType)
]
public virtual ButtonType StepNextButtonType {
get {
object obj = ViewState["StepNextButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["StepNextButtonType"] = value;
}
}
/// <devdoc>
/// Gets or sets the URL of an image to be displayed for the previous button.
/// </devdoc>
[
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
WebCategory("Appearance"),
WebSysDescription(SR.Wizard_StepPreviousButtonImageUrl),
UrlProperty(),
]
public virtual string StepPreviousButtonImageUrl {
get {
object obj = ViewState["StepPreviousButtonImageUrl"];
return (obj == null) ? String.Empty : (string)obj;
}
set {
ViewState["StepPreviousButtonImageUrl"] = value;
}
}
/// <devdoc>
/// Gets the style of the navigation buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_StepPreviousButtonStyle)
]
public Style StepPreviousButtonStyle {
get {
if (_stepPreviousButtonStyle == null) {
_stepPreviousButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_stepPreviousButtonStyle).TrackViewState();
}
}
return _stepPreviousButtonStyle;
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_StepPreviousButtonText),
WebSysDescription(SR.Wizard_StepPreviousButtonText)
]
public virtual String StepPreviousButtonText {
get {
string s = ViewState["StepPreviousButtonText"] as String;
return s == null ? SR.GetString(SR.Wizard_Default_StepPreviousButtonText) : s;
}
set {
ViewState["StepPreviousButtonText"] = value;
}
}
[
WebCategory("Appearance"),
DefaultValue(ButtonType.Button),
WebSysDescription(SR.Wizard_StepPreviousButtonType)
]
public virtual ButtonType StepPreviousButtonType {
get {
object obj = ViewState["StepPreviousButtonType"];
return (obj == null) ? ButtonType.Button : (ButtonType)obj;
}
set {
ValidateButtonType(value);
ViewState["StepPreviousButtonType"] = value;
}
}
/// <devdoc>
/// Gets the style of the side bar buttons.
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_SideBarButtonStyle)
]
public Style SideBarButtonStyle {
get {
if (_sideBarButtonStyle == null) {
_sideBarButtonStyle = new Style();
if (IsTrackingViewState) {
((IStateManager)_sideBarButtonStyle).TrackViewState();
}
}
return _sideBarButtonStyle;
}
}
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.Wizard_SideBarStyle)
]
public TableItemStyle SideBarStyle {
get {
if (_sideBarStyle == null) {
_sideBarStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_sideBarStyle).TrackViewState();
}
return _sideBarStyle;
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.Wizard_SideBarTemplate)
]
public virtual ITemplate SideBarTemplate {
get {
return _sideBarTemplate;
}
set {
_sideBarTemplate = value;
_sideBarTableCell = null;
RequiresControlsRecreation();
}
}
[
Localizable(true),
WebCategory("Appearance"),
WebSysDefaultValue(SR.Wizard_Default_SkipToContentText),
WebSysDescription(SR.WebControl_SkipLinkText)
]
public virtual String SkipLinkText {
get {
string s = SkipLinkTextInternal;
return s == null ? SR.GetString(SR.Wizard_Default_SkipToContentText) : s;
}
set {
ViewState["SkipLinkText"] = value;
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.Wizard_StartNavigationTemplate)
]
public virtual ITemplate StartNavigationTemplate {
get {
return _startNavigationTemplate;
}
set {
_startNavigationTemplate = value;
RequiresControlsRecreation();
}
}
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(Wizard)),
WebSysDescription(SR.Wizard_StepNavigationTemplate)
]
public virtual ITemplate StepNavigationTemplate {
get {
return _stepNavigationTemplate;
}
set {
_stepNavigationTemplate = value;
RequiresControlsRecreation();
}
}
[
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebCategory("Styles"),
WebSysDescription(SR.Wizard_StepStyle)
]
public TableItemStyle StepStyle {
get {
if (_stepStyle == null) {
_stepStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_stepStyle).TrackViewState();
}
return _stepStyle;
}
}
//
protected override HtmlTextWriterTag TagKey {
get {
return HtmlTextWriterTag.Table;
}
}
[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor("System.Web.UI.Design.WebControls.WizardStepCollectionEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
PersistenceMode(PersistenceMode.InnerProperty),
Themeable(false),
WebSysDescription(SR.Wizard_WizardSteps),
]
public virtual WizardStepCollection WizardSteps {
get {
if (_wizardStepCollection == null) {
_wizardStepCollection = new WizardStepCollection(this);
}
return _wizardStepCollection;
}
}
#endregion
#region Public Events
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_ActiveStepChanged)
]
public event EventHandler ActiveStepChanged {
add {
Events.AddHandler(_eventActiveStepChanged, value);
}
remove {
Events.RemoveHandler(_eventActiveStepChanged, value);
}
}
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_CancelButtonClick)
]
public event EventHandler CancelButtonClick {
add {
Events.AddHandler(_eventCancelButtonClick, value);
}
remove {
Events.RemoveHandler(_eventCancelButtonClick, value);
}
}
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_FinishButtonClick)
]
public event WizardNavigationEventHandler FinishButtonClick {
add {
Events.AddHandler(_eventFinishButtonClick, value);
}
remove {
Events.RemoveHandler(_eventFinishButtonClick, value);
}
}
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_NextButtonClick)
]
public event WizardNavigationEventHandler NextButtonClick {
add {
Events.AddHandler(_eventNextButtonClick, value);
}
remove {
Events.RemoveHandler(_eventNextButtonClick, value);
}
}
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_PreviousButtonClick)
]
public event WizardNavigationEventHandler PreviousButtonClick {
add {
Events.AddHandler(_eventPreviousButtonClick, value);
}
remove {
Events.RemoveHandler(_eventPreviousButtonClick, value);
}
}
[
WebCategory("Action"),
WebSysDescription(SR.Wizard_SideBarButtonClick)
]
public virtual event WizardNavigationEventHandler SideBarButtonClick {
add {
Events.AddHandler(_eventSideBarButtonClick, value);
}
remove {
Events.RemoveHandler(_eventSideBarButtonClick, value);
}
}
#endregion
#region Internal Properties
internal Dictionary<WizardStepBase, BaseNavigationTemplateContainer> CustomNavigationContainers {
get {
if (_customNavigationContainers == null) {
_customNavigationContainers = new Dictionary<WizardStepBase, BaseNavigationTemplateContainer>();
}
return _customNavigationContainers;
}
}
private ITemplate CustomNavigationTemplate {
get {
var templatedActiveStep = ActiveStep as TemplatedWizardStep;
return templatedActiveStep == null ? null : templatedActiveStep.CustomNavigationTemplate;
}
}
private Stack<int> History {
get {
if (_historyStack == null)
_historyStack = new Stack<int>();
return _historyStack;
}
}
private bool IsMacIE5 {
get {
if (!_isMacIE.HasValue && !DesignMode) {
HttpBrowserCapabilities browser = null;
if (Page != null) {
browser = Page.Request.Browser;
} else {
HttpContext context = HttpContext.Current;
// Context could be null if this control is created by the parser at designtime
if (context != null) {
browser = context.Request.Browser;
}
}
_isMacIE = (browser != null && browser.Type == "IE5" && browser.Platform == "MacPPC");
}
return _isMacIE.Value;
}
}
internal MultiView MultiView {
get {
if (_multiView == null) {
_multiView = new MultiView();
_multiView.EnableTheming = true;
_multiView.ID = _multiViewID;
_multiView.ActiveViewChanged += new EventHandler(this.MultiViewActiveViewChanged);
_multiView.IgnoreBubbleEvents();
}
return _multiView;
}
}
internal virtual bool ShowCustomNavigationTemplate {
get {
return CustomNavigationTemplate != null;
}
}
internal bool ShouldRenderChildControl {
get {
if (!DesignMode) {
return true;
}
if (_designModeState == null) {
return true;
}
object o = _designModeState["ShouldRenderWizardSteps"];
return o == null ? true : (bool)o;
}
}
private IWizardSideBarListControl SideBarList {
get { return _sideBarList; }
}
private bool SideBarEnabled {
get {
return _sideBarList != null && DisplaySideBar;
}
}
internal string SkipLinkTextInternal {
get {
return ViewState["SkipLinkText"] as String;
}
}
internal List<TemplatedWizardStep> TemplatedSteps {
get {
if (_templatedSteps == null) {
_templatedSteps = new List<TemplatedWizardStep>();
}
return _templatedSteps;
}
}
#endregion
private void MultiViewActiveViewChanged(object source, EventArgs e) {
OnActiveStepChanged(this, EventArgs.Empty);
}
private void ApplyControlProperties() {
_rendering.ApplyControlProperties();
}
internal BaseNavigationTemplateContainer CreateBaseNavigationTemplateContainer(string id) {
return new BaseNavigationTemplateContainer(this) {
ID = id
};
}
/// <internalonly />
protected internal override void CreateChildControls() {
using (new WizardControlCollectionModifier(this)) {
Controls.Clear();
_customNavigationContainers = null;
}
if (LayoutTemplate == null) {
_rendering = CreateTableRendering();
}
else {
_rendering = CreateLayoutTemplateRendering();
}
CreateControlHierarchy();
ClearChildViewState();
}
internal virtual TableWizardRendering CreateTableRendering() {
return new TableWizardRendering(this);
}
internal virtual LayoutTemplateWizardRendering CreateLayoutTemplateRendering() {
return new LayoutTemplateWizardRendering(this);
}
protected override ControlCollection CreateControlCollection() {
return new WizardControlCollection(this);
}
protected virtual void CreateControlHierarchy() {
_rendering.CreateControlHierarchy();
}
private void SetStepsAndDataBindSideBarList(IWizardSideBarListControl sideBarList) {
if (sideBarList != null) {
sideBarList.DataSource = WizardSteps;
sideBarList.SelectedIndex = ActiveStepIndex;
sideBarList.DataBind();
}
}
internal virtual ITemplate CreateDefaultSideBarTemplate() {
return new DefaultSideBarTemplate(this);
}
internal virtual ITemplate CreateDefaultDataListItemTemplate() {
return new DataListItemTemplate(this);
}
/// <internalonly/>
/// <devdoc>
/// <para>A protected method. Creates a table control style.</para>
/// </devdoc>
protected override Style CreateControlStyle() {
TableStyle controlStyle = new TableStyle();
// initialize defaults that are different from TableStyle
controlStyle.CellSpacing = 0;
controlStyle.CellPadding = 0;
return controlStyle;
}
internal virtual void CreateCustomNavigationTemplates() {
for (int i = 0; i < WizardSteps.Count; ++i) {
TemplatedWizardStep step = WizardSteps[i] as TemplatedWizardStep;
if (step != null) {
RegisterCustomNavigationContainers(step);
}
}
}
internal void RegisterCustomNavigationContainers(TemplatedWizardStep step) {
// Instantiate the step's ContentTemplate
InstantiateStepContentTemplate(step);
if (!CustomNavigationContainers.ContainsKey(step)) {
BaseNavigationTemplateContainer container = null;
string id = GetCustomContainerID(WizardSteps.IndexOf(step));
if (step.CustomNavigationTemplate != null) {
container = CreateBaseNavigationTemplateContainer(id);
step.CustomNavigationTemplate.InstantiateIn(container);
step.CustomNavigationTemplateContainer = container;
container.RegisterButtonCommandEvents();
} else {
container = CreateBaseNavigationTemplateContainer(id);
container.RegisterButtonCommandEvents();
}
CustomNavigationContainers[step] = container;
}
}
internal virtual void DataListItemDataBound(object sender, WizardSideBarListControlItemEventArgs e) {
var dataListItem = e.Item;
// Ignore the item that is not created from DataSource
if (dataListItem.ItemType != ListItemType.Item &&
dataListItem.ItemType != ListItemType.AlternatingItem &&
dataListItem.ItemType != ListItemType.SelectedItem &&
dataListItem.ItemType != ListItemType.EditItem) {
return;
}
IButtonControl button = dataListItem.FindControl(SideBarButtonID) as IButtonControl;
if (button == null) {
if (!DesignMode) {
throw new InvalidOperationException(
SR.GetString(SR.Wizard_SideBar_Button_Not_Found, DataListID, SideBarButtonID));
}
return;
}
var ctrlButton = button as Button;
if (ctrlButton != null) {
// Use javascript submit to use the postdata instead, this is necessarily since the buttons could be recreated during DataBind(). Previously
// registered buttons will lose their parents and events won't bubble up. VSWhidbey 120640.
// For devices that do not support Javascript, fall back to sumit behavior VSWhidbey 154576
ctrlButton.UseSubmitBehavior = false;
}
WebControl webCtrlButton = button as WebControl;
if (webCtrlButton != null) {
webCtrlButton.TabIndex = this.TabIndex;
}
int index = 0;
// Render wizardstep title on the button control.
WizardStepBase step = dataListItem.DataItem as WizardStepBase;
if (step != null) {
// Disable the button if it's a Complete step.
if (GetStepType(step) == WizardStepType.Complete &&
webCtrlButton != null) {
webCtrlButton.Enabled = false;
}
// Need to render the sidebar tablecell.
RegisterSideBarDataListForRender();
// Use the step title if defined, otherwise use ID
if (step.Title.Length > 0) {
button.Text = step.Title;
} else {
button.Text = step.ID;
}
index = WizardSteps.IndexOf(step);
button.CommandName = MoveToCommandName;
button.CommandArgument = index.ToString(NumberFormatInfo.InvariantInfo);
RegisterCommandEvents(button);
}
}
internal void RegisterSideBarDataListForRender() {
_renderSideBarDataList = true;
}
private void DataListItemCommand(object sender, CommandEventArgs e) {
if (!MoveToCommandName.Equals(e.CommandName, StringComparison.OrdinalIgnoreCase)) {
return;
}
int oldIndex = ActiveStepIndex;
int newIndex = Int32.Parse((String)e.CommandArgument, CultureInfo.InvariantCulture);
WizardNavigationEventArgs args = new WizardNavigationEventArgs(oldIndex, newIndex);
// Never cancel the item command at design time.
if (_commandSender != null && !DesignMode && Page != null && !Page.IsValid) {
args.Cancel = true;
}
_activeStepIndexSet = false;
OnSideBarButtonClick(args);
if (!args.Cancel) {
// Honor user's change if activeStepIndex is set explicitely;
if (!_activeStepIndexSet) {
if (AllowNavigationToStep(newIndex)) {
ActiveStepIndex = newIndex;
}
}
} else {
// revert active step if it's cancelled.
ActiveStepIndex = oldIndex;
}
}
internal static string GetCustomContainerID(int index) {
return _customNavigationContainerIdPrefix + index;
}
/// <internalonly/>
[SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
protected override IDictionary GetDesignModeState() {
IDictionary dictionary = base.GetDesignModeState();
Debug.Assert(dictionary != null && DesignMode);
_designModeState = dictionary;
int oldIndex = ActiveStepIndex;
// Set the activestepindex to 0 in designmode if it's -1.
try {
if (oldIndex == -1 && WizardSteps.Count > 0) {
ActiveStepIndex = 0;
}
RequiresControlsRecreation();
EnsureChildControls();
ApplyControlProperties();
_rendering.SetDesignModeState(dictionary);
if (ShowCustomNavigationTemplate) {
BaseNavigationTemplateContainer customContainer = CustomNavigationContainers[ActiveStep];
dictionary[CustomNextButtonID] = customContainer.NextButton;
dictionary[CustomPreviousButtonID] = customContainer.PreviousButton;
dictionary[CustomFinishButtonID] = customContainer.FinishButton;
dictionary[CancelButtonID] = customContainer.CancelButton;
dictionary[_customNavigationControls] = customContainer.Controls;
}
// VSWhidbey 456506. Reset the ItemTemplate so it can be persisted correctly
// based on current SideBarButtonStyle
if (SideBarTemplate == null && _sideBarList != null) {
_sideBarList.ItemTemplate = CreateDefaultDataListItemTemplate();
}
dictionary[DataListID] = _sideBarList;
dictionary[_templatedStepsID] = TemplatedSteps;
} finally {
ActiveStepIndex = oldIndex;
}
return dictionary;
}
public ICollection GetHistory() {
ArrayList list = new ArrayList();
foreach (int index in History) {
list.Add(WizardSteps[index]);
}
return list;
}
internal int GetPreviousStepIndex(bool popStack) {
int previousIndex = -1;
int index = ActiveStepIndex;
if (_historyStack == null || _historyStack.Count == 0) {
return previousIndex;
}
if (popStack) {
previousIndex = _historyStack.Pop();
// Ignore the current step, the current step index is already in the historyStack.
if (previousIndex == index && _historyStack.Count > 0) {
previousIndex = _historyStack.Pop();
}
} else {
previousIndex = _historyStack.Peek();
// Ignore the current step, the current step index is already in the historyStack.
if (previousIndex == index && _historyStack.Count > 1) {
int originalIndex = _historyStack.Pop();
previousIndex = _historyStack.Peek();
_historyStack.Push(originalIndex);
}
}
// Return -1 if the current step is same as previous step
if (previousIndex == index) {
return -1;
}
return previousIndex;
}
private WizardStepType GetStepType(int index) {
Debug.Assert(index > -1 && index < WizardSteps.Count);
WizardStepBase step = WizardSteps[index] as WizardStepBase;
return GetStepType(step, index);
}
private WizardStepType GetStepType(WizardStepBase step) {
int index = WizardSteps.IndexOf(step);
return GetStepType(step, index);
}
public WizardStepType GetStepType(WizardStepBase wizardStep, int index) {
if (wizardStep.StepType == WizardStepType.Auto) {
// If it's the only step or a Complete step is after current step, then make it Finish step
if (WizardSteps.Count == 1 ||
(index < WizardSteps.Count - 1 &&
WizardSteps[index + 1].StepType == WizardStepType.Complete)) {
return WizardStepType.Finish;
}
// First one is the start step
if (index == 0) {
return WizardStepType.Start;
}
// Last one is the finish step
if (index == WizardSteps.Count - 1) {
return WizardStepType.Finish;
}
return WizardStepType.Step;
}
return wizardStep.StepType;
}
/// <devdoc>
/// Instantiates all the content templates for each TemplatedWizardStep
/// </devdoc>
internal virtual void InstantiateStepContentTemplates() {
TemplatedSteps.ForEach(step => InstantiateStepContentTemplate(step));
}
internal void InstantiateStepContentTemplate(TemplatedWizardStep step) {
step.Controls.Clear();
BaseContentTemplateContainer container = new BaseContentTemplateContainer(this, true);
ITemplate contentTemplate = step.ContentTemplate;
if (contentTemplate != null) {
container.SetEnableTheming();
contentTemplate.InstantiateIn(container.InnerCell);
}
step.ContentTemplateContainer = container;
step.Controls.Add(container);
}
/// <devdoc>
/// <para>Loads the control state.</para>
/// </devdoc>
protected internal override void LoadControlState(object state) {
Triplet t = state as Triplet;
if (t != null) {
base.LoadControlState(t.First);
Array collection = t.Second as Array;
if (collection != null) {
Array.Reverse(collection);
_historyStack = new Stack<int>(collection.Cast<int>());
}
ActiveStepIndex = (int)t.Third;
}
}
protected override void LoadViewState(object savedState) {
if (savedState == null) {
base.LoadViewState(null);
} else {
object[] myState = (object[])savedState;
if (myState.Length != _viewStateArrayLength) {
throw new ArgumentException(SR.GetString(SR.ViewState_InvalidViewState));
}
base.LoadViewState(myState[0]);
if (myState[1] != null)
((IStateManager)NavigationButtonStyle).LoadViewState(myState[1]);
if (myState[2] != null)
((IStateManager)SideBarButtonStyle).LoadViewState(myState[2]);
if (myState[3] != null)
((IStateManager)HeaderStyle).LoadViewState(myState[3]);
if (myState[4] != null)
((IStateManager)NavigationStyle).LoadViewState(myState[4]);
if (myState[5] != null)
((IStateManager)SideBarStyle).LoadViewState(myState[5]);
if (myState[6] != null)
((IStateManager)StepStyle).LoadViewState(myState[6]);
if (myState[7] != null)
((IStateManager)StartNextButtonStyle).LoadViewState(myState[7]);
if (myState[8] != null)
((IStateManager)StepNextButtonStyle).LoadViewState(myState[8]);
if (myState[9] != null)
((IStateManager)StepPreviousButtonStyle).LoadViewState(myState[9]);
if (myState[10] != null)
((IStateManager)FinishPreviousButtonStyle).LoadViewState(myState[10]);
if (myState[11] != null)
((IStateManager)FinishCompleteButtonStyle).LoadViewState(myState[11]);
if (myState[12] != null)
((IStateManager)CancelButtonStyle).LoadViewState(myState[12]);
if (myState[13] != null)
((IStateManager)ControlStyle).LoadViewState(myState[13]);
if (myState[14] != null)
DisplaySideBar = (bool)myState[14];
}
}
public void MoveTo(WizardStepBase wizardStep) {
if (wizardStep == null)
throw new ArgumentNullException("wizardStep");
int index = WizardSteps.IndexOf(wizardStep);
if (index == -1) {
throw new ArgumentException(SR.GetString(SR.Wizard_Step_Not_In_Wizard));
}
ActiveStepIndex = index;
}
protected virtual void OnActiveStepChanged(object source, EventArgs e) {
EventHandler handler = (EventHandler)Events[_eventActiveStepChanged];
if (handler != null) handler(this, e);
}
protected override bool OnBubbleEvent(object source, EventArgs e) {
bool handled = false;
CommandEventArgs ce = e as CommandEventArgs;
if (ce != null) {
if (String.Equals(CancelCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
OnCancelButtonClick(EventArgs.Empty);
return true;
}
int oldIndex = ActiveStepIndex;
int newIndex = oldIndex;
// Check if we need to validate the bubble commands VSWhidbey 312445
bool verifyEvent = true;
WizardStepType stepType = WizardStepType.Auto;
WizardStepBase step = WizardSteps[oldIndex];
// Don't validate commands if it's a templated wizard step
if (step is TemplatedWizardStep) {
verifyEvent = false;
} else {
stepType = GetStepType(step);
}
WizardNavigationEventArgs args = new WizardNavigationEventArgs(oldIndex, newIndex);
// Do not navigate away from current view if view is not valid.
if (_commandSender != null && Page != null && !Page.IsValid) {
args.Cancel = true;
}
bool previousButtonCommand = false;
_activeStepIndexSet = false;
if (String.Equals(MoveNextCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
if (verifyEvent) {
if (stepType != WizardStepType.Start && stepType != WizardStepType.Step) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MoveNextCommandName));
}
}
if (oldIndex < WizardSteps.Count - 1) {
args.SetNextStepIndex(oldIndex + 1);
}
OnNextButtonClick(args);
handled = true;
} else if (String.Equals(MovePreviousCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
if (verifyEvent) {
if (stepType != WizardStepType.Step && stepType != WizardStepType.Finish) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MovePreviousCommandName));
}
}
previousButtonCommand = true;
int previousIndex = GetPreviousStepIndex(false);
if (previousIndex != -1) {
args.SetNextStepIndex(previousIndex);
}
OnPreviousButtonClick(args);
handled = true;
} else if (String.Equals(MoveCompleteCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
if (verifyEvent) {
if (stepType != WizardStepType.Finish) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_InvalidBubbleEvent, MoveCompleteCommandName));
}
}
if (oldIndex < WizardSteps.Count - 1) {
args.SetNextStepIndex(oldIndex + 1);
}
OnFinishButtonClick(args);
handled = true;
} else if (String.Equals(MoveToCommandName, ce.CommandName, StringComparison.OrdinalIgnoreCase)) {
newIndex = Int32.Parse((String)ce.CommandArgument, CultureInfo.InvariantCulture);
args.SetNextStepIndex(newIndex);
handled = true;
}
if (handled) {
if (!args.Cancel) {
// Honor user's change if activeStepIndex is set explicitely;
if (!_activeStepIndexSet) {
// Make sure the next step is valid to navigate to
if (AllowNavigationToStep(args.NextStepIndex)) {
if (previousButtonCommand) {
GetPreviousStepIndex(true);
}
ActiveStepIndex = args.NextStepIndex;
}
}
} else {
// revert active step if it's cancelled.
ActiveStepIndex = oldIndex;
}
}
}
return handled;
}
internal void OnWizardStepsChanged() {
SetStepsAndDataBindSideBarList(_sideBarList);
}
protected virtual bool AllowNavigationToStep(int index) {
if (_historyStack != null && _historyStack.Contains(index)) {
return WizardSteps[index].AllowReturn;
}
return true;
}
protected virtual void OnCancelButtonClick(EventArgs e) {
EventHandler handler = (EventHandler)Events[_eventCancelButtonClick];
if (handler != null) {
handler(this, e);
}
string cancelDestinationUrl = CancelDestinationPageUrl;
if (!String.IsNullOrEmpty(cancelDestinationUrl)) {
Page.Response.Redirect(ResolveClientUrl(cancelDestinationUrl), false);
}
}
private void OnCommand(object sender, CommandEventArgs e) {
Debug.Assert(_commandSender == null);
_commandSender = sender as IButtonControl;
}
protected virtual void OnFinishButtonClick(WizardNavigationEventArgs e) {
WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventFinishButtonClick];
if (handler != null) handler(this, e);
string finishPageUrl = FinishDestinationPageUrl;
if (!String.IsNullOrEmpty(finishPageUrl)) {
// Microsoft suggested that we should not terminate execution of current page, to give
// page a chance to cleanup its resources. This may be less performant though.
// Microsoft suggested that we need to call ResolveClientUrl before redirecting.
// Example is this control inside user control, want redirect relative to user control dir.
Page.Response.Redirect(ResolveClientUrl(finishPageUrl), false);
}
}
protected internal override void OnInit(EventArgs e) {
base.OnInit(e);
// Always set the current step to the first step if not specified.
if (ActiveStepIndex == -1 && WizardSteps.Count > 0 && !DesignMode) {
ActiveStepIndex = 0;
}
// Add default control layout during OnInit to track WizardStep viewstate properly.
EnsureChildControls();
if (Page != null) {
Page.RegisterRequiresControlState(this);
}
}
protected virtual void OnNextButtonClick(WizardNavigationEventArgs e) {
WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventNextButtonClick];
if (handler != null) handler(this, e);
}
protected virtual void OnPreviousButtonClick(WizardNavigationEventArgs e) {
WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventPreviousButtonClick];
if (handler != null) handler(this, e);
}
protected virtual void OnSideBarButtonClick(WizardNavigationEventArgs e) {
WizardNavigationEventHandler handler = (WizardNavigationEventHandler)Events[_eventSideBarButtonClick];
if (handler != null) handler(this, e);
}
internal void RequiresControlsRecreation() {
if (ChildControlsCreated) {
using (new WizardControlCollectionModifier(this)) {
base.ChildControlsCreated = false;
}
_rendering = null;
}
}
protected internal void RegisterCommandEvents(IButtonControl button) {
if (button != null && button.CausesValidation) {
button.Command += new CommandEventHandler(this.OnCommand);
}
}
protected internal override void Render(HtmlTextWriter writer) {
// Make sure we're in runat=server form.
if (Page != null) {
Page.VerifyRenderingInServerForm(this);
}
EnsureChildControls();
ApplyControlProperties();
// Nothing to do if the Wizard is empty;
if (ActiveStepIndex == -1 || WizardSteps.Count == 0) {
return;
}
RenderContents(writer);
}
protected internal override object SaveControlState() {
int activeStepIndex = ActiveStepIndex;
// Save the ActiveStepIndex here so steps dynamically added
// before or during OnPagePreRenderComplete will be tracked
// properly. See VSWhidbey 395312
if (_historyStack == null || _historyStack.Count == 0 ||
_historyStack.Peek() != activeStepIndex) {
// Remember the active step.
History.Push(ActiveStepIndex);
}
object obj = base.SaveControlState();
bool containsHistory = _historyStack != null && _historyStack.Count > 0;
if (obj != null || containsHistory || activeStepIndex != -1) {
object array = containsHistory ? _historyStack.ToArray() : null;
return new Triplet(obj, array, activeStepIndex);
}
return null;
}
protected override object SaveViewState() {
object[] myState = new object[_viewStateArrayLength];
Debug.Assert(_viewStateArrayLength == 15, "Forgot to change array length when adding new item to view state?");
myState[0] = base.SaveViewState();
myState[1] = (_navigationButtonStyle != null) ? ((IStateManager)_navigationButtonStyle).SaveViewState() : null;
myState[2] = (_sideBarButtonStyle != null) ? ((IStateManager)_sideBarButtonStyle).SaveViewState() : null;
myState[3] = (_headerStyle != null) ? ((IStateManager)_headerStyle).SaveViewState() : null;
myState[4] = (_navigationStyle != null) ? ((IStateManager)_navigationStyle).SaveViewState() : null;
myState[5] = (_sideBarStyle != null) ? ((IStateManager)_sideBarStyle).SaveViewState() : null;
myState[6] = (_stepStyle != null) ? ((IStateManager)_stepStyle).SaveViewState() : null;
myState[7] = (_startNextButtonStyle != null) ? ((IStateManager)_startNextButtonStyle).SaveViewState() : null;
myState[8] = (_stepNextButtonStyle != null) ? ((IStateManager)_stepNextButtonStyle).SaveViewState() : null;
myState[9] = (_stepPreviousButtonStyle != null) ? ((IStateManager)_stepPreviousButtonStyle).SaveViewState() : null;
myState[10] = (_finishPreviousButtonStyle != null) ? ((IStateManager)_finishPreviousButtonStyle).SaveViewState() : null;
myState[11] = (_finishCompleteButtonStyle != null) ? ((IStateManager)_finishCompleteButtonStyle).SaveViewState() : null;
myState[12] = (_cancelButtonStyle != null) ? ((IStateManager)_cancelButtonStyle).SaveViewState() : null;
myState[13] = ControlStyleCreated ? ((IStateManager)ControlStyle).SaveViewState() : null;
if (DisplaySideBar != _displaySideBarDefault) {
myState[14] = DisplaySideBar;
}
for (int i = 0; i < _viewStateArrayLength; i++) {
if (myState[i] != null) {
return myState;
}
}
// More performant to return null than an array of null values
return null;
}
private void SetCancelButtonVisibility(BaseNavigationTemplateContainer container) {
// Make the parent TD invisible if possible.
Control c = container.CancelButton as Control;
if (c != null) {
Control parent = c.Parent;
if (parent != null) {
Debug.Assert(parent is TableCell);
parent.Visible = DisplayCancelButton;
}
c.Visible = DisplayCancelButton;
}
}
protected override void TrackViewState() {
base.TrackViewState();
if (_navigationButtonStyle != null)
((IStateManager)_navigationButtonStyle).TrackViewState();
if (_sideBarButtonStyle != null)
((IStateManager)_sideBarButtonStyle).TrackViewState();
if (_headerStyle != null)
((IStateManager)_headerStyle).TrackViewState();
if (_navigationStyle != null)
((IStateManager)_navigationStyle).TrackViewState();
if (_sideBarStyle != null)
((IStateManager)_sideBarStyle).TrackViewState();
if (_stepStyle != null)
((IStateManager)_stepStyle).TrackViewState();
if (_startNextButtonStyle != null)
((IStateManager)_startNextButtonStyle).TrackViewState();
if (_stepPreviousButtonStyle != null)
((IStateManager)_stepPreviousButtonStyle).TrackViewState();
if (_stepNextButtonStyle != null)
((IStateManager)_stepNextButtonStyle).TrackViewState();
if (_finishPreviousButtonStyle != null)
((IStateManager)_finishPreviousButtonStyle).TrackViewState();
if (_finishCompleteButtonStyle != null)
((IStateManager)_finishCompleteButtonStyle).TrackViewState();
if (_cancelButtonStyle != null)
((IStateManager)_cancelButtonStyle).TrackViewState();
if (ControlStyleCreated) {
((IStateManager)ControlStyle).TrackViewState();
}
}
private static void ValidateButtonType(ButtonType value) {
if (value < ButtonType.Button || value > ButtonType.Link) {
throw new ArgumentOutOfRangeException("value");
}
}
#region Rendering Abstractions
internal abstract class WizardRenderingBase {
private const string _startNavigationTemplateContainerID = "StartNavigationTemplateContainerID";
private const string _stepNavigationTemplateContainerID = "StepNavigationTemplateContainerID";
private const string _finishNavigationTemplateContainerID = "FinishNavigationTemplateContainerID";
private NavigationTemplate _defaultStartNavigationTemplate;
private NavigationTemplate _defaultStepNavigationTemplate;
private NavigationTemplate _defaultFinishNavigationTemplate;
protected BaseNavigationTemplateContainer _finishNavigationTemplateContainer;
protected BaseNavigationTemplateContainer _startNavigationTemplateContainer;
protected BaseNavigationTemplateContainer _stepNavigationTemplateContainer;
protected Wizard Owner { get; private set; }
protected WizardRenderingBase(Wizard wizard) {
Owner = wizard;
}
public abstract void ApplyControlProperties();
public abstract void CreateControlHierarchy();
public virtual void SetDesignModeState(IDictionary dictionary) {
if (_startNavigationTemplateContainer != null) {
dictionary[StartNextButtonID] = _startNavigationTemplateContainer.NextButton;
dictionary[CancelButtonID] = _startNavigationTemplateContainer.CancelButton;
}
if (_stepNavigationTemplateContainer != null) {
dictionary[StepNextButtonID] = _stepNavigationTemplateContainer.NextButton;
dictionary[StepPreviousButtonID] = _stepNavigationTemplateContainer.PreviousButton;
dictionary[CancelButtonID] = _stepNavigationTemplateContainer.CancelButton;
}
if (_finishNavigationTemplateContainer != null) {
dictionary[FinishPreviousButtonID] = _finishNavigationTemplateContainer.PreviousButton;
dictionary[FinishButtonID] = _finishNavigationTemplateContainer.FinishButton;
dictionary[CancelButtonID] = _finishNavigationTemplateContainer.CancelButton;
}
}
protected void ApplyControlProperties_Sidebar() {
if (Owner.SideBarEnabled) {
Owner.SetStepsAndDataBindSideBarList(Owner._sideBarList);
// Only apply the styles to the sidebar or sidebar buttons if custom template is not used.
if (Owner.SideBarTemplate == null) {
foreach (Control item in Owner._sideBarList.Items) {
WebControl button = item.FindControl(SideBarButtonID) as WebControl;
if (button != null) {
button.MergeStyle(Owner._sideBarButtonStyle);
}
}
}
}
}
protected void ApplyNavigationTemplateProperties() {
// Do not apply any template properties if the containers are null
// This happens when GetDesignModeState is called before child controls are created.
if (_finishNavigationTemplateContainer == null ||
_startNavigationTemplateContainer == null ||
_stepNavigationTemplateContainer == null) {
return;
}
WizardStepType renderType = WizardStepType.Start;
// Set the active templates based on ActiveStep
// Make sure the activestepindex is valid. // VSWhidbey 376438
if (Owner.ActiveStepIndex >= Owner.WizardSteps.Count || Owner.ActiveStepIndex < 0) {
return;
}
renderType = SetActiveTemplates();
bool requiresFinishPreviousButton =
renderType != WizardStepType.Finish || Owner.ActiveStepIndex != 0 || Owner.ActiveStep.StepType != WizardStepType.Auto;
ApplyDefaultStartNavigationTemplateProperties();
bool showPrevious = true;
int prevStepIndex = Owner.GetPreviousStepIndex(false);
if (prevStepIndex >= 0) {
showPrevious = Owner.WizardSteps[prevStepIndex].AllowReturn;
}
ApplyDefaultFinishNavigationTemplateProperties(showPrevious);
ApplyDefaultStepNavigationTemplateProperties(showPrevious);
// if the first step using auto type is assigned to a finish step, do not render the previous button's container.
if (!requiresFinishPreviousButton) {
Control ctrl = _finishNavigationTemplateContainer.PreviousButton as Control;
if (ctrl != null) {
if (Owner.FinishNavigationTemplate == null) {
ctrl.Parent.Visible = false;
} else {
ctrl.Visible = false;
}
}
}
}
private void ApplyDefaultStepNavigationTemplateProperties(bool previousImageButtonVisible) {
// Only apply properties to the default template (if a custom template has not been specified)
if (Owner.StepNavigationTemplate != null) {
return;
}
var navContainer = _stepNavigationTemplateContainer;
NavigationTemplate defaultTemplate = _defaultStepNavigationTemplate;
if (Owner.DesignMode) {
defaultTemplate.ResetButtonsVisibility();
}
navContainer.PreviousButton = defaultTemplate.FirstButton;
((Control)navContainer.PreviousButton).Visible = true;
navContainer.NextButton = defaultTemplate.SecondButton;
((Control)navContainer.NextButton).Visible = true;
navContainer.CancelButton = defaultTemplate.CancelButton;
ApplyButtonProperties(navContainer.NextButton, Owner.StepNextButtonText, Owner.StepNextButtonImageUrl);
ApplyButtonProperties(navContainer.PreviousButton, Owner.StepPreviousButtonText, Owner.StepPreviousButtonImageUrl, previousImageButtonVisible);
ApplyButtonProperties(navContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
int previousStepIndex = Owner.GetPreviousStepIndex(false);
if (previousStepIndex != -1 && !Owner.WizardSteps[previousStepIndex].AllowReturn) {
((Control)navContainer.PreviousButton).Visible = false;
}
Owner.SetCancelButtonVisibility(navContainer);
navContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.StepPreviousButtonStyle, Owner.StepNextButtonStyle, Owner.CancelButtonStyle);
}
private void ApplyDefaultFinishNavigationTemplateProperties(bool previousImageButtonVisible) {
// Only apply properties to the default template (if a custom template has not been specified)
if (Owner.FinishNavigationTemplate != null) {
return;
}
var finishContainer = _finishNavigationTemplateContainer;
NavigationTemplate defaultTemplate = _defaultFinishNavigationTemplate;
if (Owner.DesignMode) {
defaultTemplate.ResetButtonsVisibility();
}
finishContainer.PreviousButton = defaultTemplate.FirstButton;
((Control)finishContainer.PreviousButton).Visible = true;
finishContainer.FinishButton = defaultTemplate.SecondButton;
((Control)finishContainer.FinishButton).Visible = true;
finishContainer.CancelButton = defaultTemplate.CancelButton;
finishContainer.FinishButton.CommandName = MoveCompleteCommandName;
ApplyButtonProperties(finishContainer.FinishButton, Owner.FinishCompleteButtonText, Owner.FinishCompleteButtonImageUrl);
ApplyButtonProperties(finishContainer.PreviousButton, Owner.FinishPreviousButtonText, Owner.FinishPreviousButtonImageUrl, previousImageButtonVisible);
ApplyButtonProperties(finishContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
int previousStepIndex = Owner.GetPreviousStepIndex(false);
if (previousStepIndex != -1 && !Owner.WizardSteps[previousStepIndex].AllowReturn) {
((Control)finishContainer.PreviousButton).Visible = false;
}
Owner.SetCancelButtonVisibility(finishContainer);
finishContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.FinishPreviousButtonStyle, Owner.StepNextButtonStyle, Owner.CancelButtonStyle);
}
private void ApplyDefaultStartNavigationTemplateProperties() {
// Only apply properties to the default template (if a custom template has not been specified)
if (Owner.StartNavigationTemplate != null) {
return;
}
var startContainer = _startNavigationTemplateContainer;
NavigationTemplate defaultStartTemplate = _defaultStartNavigationTemplate;
if (Owner.DesignMode) {
defaultStartTemplate.ResetButtonsVisibility();
}
startContainer.NextButton = defaultStartTemplate.SecondButton;
((Control)startContainer.NextButton).Visible = true;
startContainer.CancelButton = defaultStartTemplate.CancelButton;
ApplyButtonProperties(startContainer.NextButton, Owner.StartNextButtonText, Owner.StartNextButtonImageUrl);
ApplyButtonProperties(startContainer.CancelButton, Owner.CancelButtonText, Owner.CancelButtonImageUrl);
Owner.SetCancelButtonVisibility(startContainer);
startContainer.ApplyButtonStyle(Owner.FinishCompleteButtonStyle, Owner.StepPreviousButtonStyle, Owner.StartNextButtonStyle, Owner.CancelButtonStyle);
}
protected virtual WizardStepType SetActiveTemplates() {
WizardStepType type = Owner.GetStepType(Owner.ActiveStepIndex);
_startNavigationTemplateContainer.Visible = (type == WizardStepType.Start);
_stepNavigationTemplateContainer.Visible = (type == WizardStepType.Step);
_finishNavigationTemplateContainer.Visible = (type == WizardStepType.Finish);
// Do not render header or sidebarlist in complete steps;
if (type == WizardStepType.Complete) {
OnlyShowCompleteStep();
}
return type;
}
private static void ApplyButtonProperties(IButtonControl button, string text, string imageUrl) {
ApplyButtonProperties(button, text, imageUrl, true);
}
private static void ApplyButtonProperties(IButtonControl button, string text, string imageUrl, bool imageButtonVisible) {
if (button == null) {
return;
}
ImageButton imageButton = button as ImageButton;
if (imageButton != null) {
imageButton.ImageUrl = imageUrl;
imageButton.AlternateText = text;
imageButton.Visible = imageButtonVisible;
} else {
button.Text = text;
}
}
public abstract void OnlyShowCompleteStep();
protected void ApplyCustomNavigationTemplateProperties() {
// Make all custom navigation containers invisible
foreach (BaseNavigationTemplateContainer c in Owner.CustomNavigationContainers.Values) {
c.Visible = false;
}
// If we are going to show a custom navigation template, make that one visible
if (Owner.ShowCustomNavigationTemplate) {
BaseNavigationTemplateContainer container = Owner._customNavigationContainers[Owner.ActiveStep];
container.Visible = true;
_startNavigationTemplateContainer.Visible = false;
_stepNavigationTemplateContainer.Visible = false;
_finishNavigationTemplateContainer.Visible = false;
}
}
protected void CreateControlHierarchy_CleanUpOldSideBarList(IWizardSideBarListControl sideBarList) {
// Remove obsolete events from sideBarDataList
if (sideBarList != null) {
sideBarList.ItemCommand -= new CommandEventHandler(Owner.DataListItemCommand);
sideBarList.ItemDataBound -= new EventHandler<WizardSideBarListControlItemEventArgs>(Owner.DataListItemDataBound);
}
}
protected IWizardSideBarListControl CreateControlHierarchy_SetUpSideBarList(Control sideBarContainer) {
var sideBarList = sideBarContainer.FindControl(DataListID) as IWizardSideBarListControl;
if (sideBarList != null) {
sideBarList.ItemCommand += new CommandEventHandler(Owner.DataListItemCommand);
sideBarList.ItemDataBound += new EventHandler<WizardSideBarListControlItemEventArgs>(Owner.DataListItemDataBound);
if (Owner.DesignMode) {
// This line is necessary for ListView to databind correctly to the list of steps when
// viewing the control on the design surface. ListView will not databind automatically when
// it is not a top-level control (as is the case here) unless the flag has a value.
((IControlDesignerAccessor)sideBarList).GetDesignModeState()["EnableDesignTimeDataBinding"] = true;
}
Owner.SetStepsAndDataBindSideBarList(sideBarList);
} else {
// Do not throw at designmode otherwise template will not be persisted correctly.
if (!Owner.DesignMode) {
throw new InvalidOperationException(
SR.GetString(SR.Wizard_DataList_Not_Found, DataListID));
}
}
return sideBarList;
}
// Helper method to create navigation templates.
protected void CreateNavigationControlHierarchy(Control container) {
container.Controls.Clear();
Owner.CustomNavigationContainers.Clear();
Owner.CreateCustomNavigationTemplates();
foreach (BaseNavigationTemplateContainer c in Owner.CustomNavigationContainers.Values) {
container.Controls.Add(c);
}
CreateStartNavigationTemplate(container);
CreateFinishNavigationTemplate(container);
CreateStepNavigationTemplate(container);
}
private void CreateStartNavigationTemplate(Control container) {
// Start navigation template
ITemplate startNavigationTemplate = Owner.StartNavigationTemplate;
_startNavigationTemplateContainer = new StartNavigationTemplateContainer(Owner);
_startNavigationTemplateContainer.ID = _startNavigationTemplateContainerID;
// Use the default template
if (startNavigationTemplate == null) {
_startNavigationTemplateContainer.EnableViewState = false;
_defaultStartNavigationTemplate = NavigationTemplate.GetDefaultStartNavigationTemplate(Owner);
startNavigationTemplate = _defaultStartNavigationTemplate;
} else {
// Custom template is used here.
_startNavigationTemplateContainer.SetEnableTheming();
}
startNavigationTemplate.InstantiateIn(_startNavigationTemplateContainer);
container.Controls.Add(_startNavigationTemplateContainer);
}
private void CreateStepNavigationTemplate(Control container) {
// step navigation template
ITemplate stepNavigationTemplate = Owner.StepNavigationTemplate;
_stepNavigationTemplateContainer = new StepNavigationTemplateContainer(Owner);
_stepNavigationTemplateContainer.ID = _stepNavigationTemplateContainerID;
if (stepNavigationTemplate == null) {
_stepNavigationTemplateContainer.EnableViewState = false;
_defaultStepNavigationTemplate = NavigationTemplate.GetDefaultStepNavigationTemplate(Owner);
stepNavigationTemplate = _defaultStepNavigationTemplate;
} else {
_stepNavigationTemplateContainer.SetEnableTheming();
}
stepNavigationTemplate.InstantiateIn(_stepNavigationTemplateContainer);
container.Controls.Add(_stepNavigationTemplateContainer);
}
private void CreateFinishNavigationTemplate(Control container) {
// finish navigation template
ITemplate finishNavigationTemplate = Owner.FinishNavigationTemplate;
_finishNavigationTemplateContainer = new FinishNavigationTemplateContainer(Owner);
_finishNavigationTemplateContainer.ID = _finishNavigationTemplateContainerID;
if (finishNavigationTemplate == null) {
_finishNavigationTemplateContainer.EnableViewState = false;
_defaultFinishNavigationTemplate = NavigationTemplate.GetDefaultFinishNavigationTemplate(Owner);
finishNavigationTemplate = _defaultFinishNavigationTemplate;
} else {
_finishNavigationTemplateContainer.SetEnableTheming();
}
finishNavigationTemplate.InstantiateIn(_finishNavigationTemplateContainer);
container.Controls.Add(_finishNavigationTemplateContainer);
}
}
internal class LayoutTemplateWizardRendering : WizardRenderingBase {
private Literal _headerLiteral;
private WizardContainer _layoutContainer;
public LayoutTemplateWizardRendering(Wizard wizard)
: base(wizard) {
}
public override void ApplyControlProperties() {
ApplyControlProperties_Header();
ApplyControlProperties_Sidebar();
// nothing interesting to apply to the wizard steps
ApplyControlProperties_Navigation();
}
private void ApplyControlProperties_Navigation() {
ApplyNavigationTemplateProperties();
ApplyCustomNavigationTemplateProperties();
}
private void ApplyControlProperties_Header() {
if (Owner.HeaderTemplate != null) {
// nothing to apply if there is a header template
return;
}
if (_headerLiteral != null) {
// not necessary to set the literal to not visible if the text is empty because a
// literal with empty text does not render anything
_headerLiteral.Text = Owner.HeaderText;
} else if (!String.IsNullOrEmpty(Owner.HeaderText)) {
// only throw if the headertext is set and there is no headerLiteral. This means
// that the layout template did not contain a header placeholder.
throw new InvalidOperationException(SR.GetString(SR.Wizard_Header_Placeholder_Must_Be_Specified_For_HeaderText, Owner.ID, HeaderPlaceholderId));
}
}
public override void OnlyShowCompleteStep() {
_layoutContainer.ControlToRender = Owner.MultiView;
}
public override void CreateControlHierarchy() {
_layoutContainer = new WizardContainer();
Owner.LayoutTemplate.InstantiateIn(_layoutContainer);
using (new WizardControlCollectionModifier(Owner)) {
Owner.Controls.Add(_layoutContainer);
}
CreateControlHierarchy_Header(_layoutContainer);
CreateControlHierarchy_SideBar(_layoutContainer);
CreateControlHierarchy_WizardStep(_layoutContainer);
CreateControlHierarchy_Navigation(_layoutContainer);
}
private void CreateControlHierarchy_Navigation(Control layoutContainer) {
var placeholder = layoutContainer.FindControl(NavigationPlaceholderId);
if (placeholder == null) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_Navigation_Placeholder_Must_Be_Specified, Owner.ID, NavigationPlaceholderId));
}
Control navigationContainer = new Control();
ReplacePlaceholderWithControl(layoutContainer, placeholder, navigationContainer);
CreateNavigationControlHierarchy(navigationContainer);
}
private void CreateControlHierarchy_Header(Control layoutContainer) {
var placeholder = layoutContainer.FindControl(HeaderPlaceholderId);
if (Owner.HeaderTemplate != null) {
if (placeholder == null) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_Header_Placeholder_Must_Be_Specified_For_HeaderTemplate, Owner.ID, HeaderPlaceholderId));
} else {
// just replace the placeholder with the template
ReplacePlaceholderWithTemplateInstance(layoutContainer, placeholder, Owner.HeaderTemplate);
}
} else if (placeholder != null) {
// only create a header literal if the template contains a placeholder
// if the template does not contain a placeholder an exception will be thrown from
// ApplyControlProperties
_headerLiteral = new Literal();
ReplacePlaceholderWithControl(layoutContainer, placeholder, _headerLiteral);
}
}
private void CreateControlHierarchy_SideBar(Control layoutContainer) {
if (!Owner.DisplaySideBar) {
// it's ok to exit here since changing the DisplaySideBar value would
// force a recreation of the control tree.
return;
}
var placeholder = layoutContainer.FindControl(SideBarPlaceholderId);
if (placeholder == null) {
//
throw new InvalidOperationException(SR.GetString(SR.Wizard_Sidebar_Placeholder_Must_Be_Specified, Owner.ID, SideBarPlaceholderId));
}
ITemplate sideBarTemplate = Owner.SideBarTemplate ?? Owner.CreateDefaultSideBarTemplate();
ReplacePlaceholderWithTemplateInstance(layoutContainer, placeholder, sideBarTemplate);
CreateControlHierarchy_CleanUpOldSideBarList(Owner.SideBarList);
Owner._sideBarList = CreateControlHierarchy_SetUpSideBarList(layoutContainer);
}
private void CreateControlHierarchy_WizardStep(Control layoutContainer) {
var placeholder = layoutContainer.FindControl(WizardStepPlaceholderId);
if (placeholder == null) {
throw new InvalidOperationException(SR.GetString(SR.Wizard_Step_Placeholder_Must_Be_Specified, Owner.ID, WizardStepPlaceholderId));
}
ReplacePlaceholderWithControl(layoutContainer, placeholder, Owner.MultiView);
}
private static void ReplacePlaceholderWithTemplateInstance(Control targetContainer, Control placeholder, ITemplate template) {
var templateContainer = new Control();
template.InstantiateIn(templateContainer);
ReplacePlaceholderWithControl(targetContainer, placeholder, templateContainer);
}
private static void ReplacePlaceholderWithControl(Control targetContainer, Control placeholder, Control replacement) {
var placeholderIndex = targetContainer.Controls.IndexOf(placeholder);
targetContainer.Controls.RemoveAt(placeholderIndex);
targetContainer.Controls.AddAt(placeholderIndex, replacement);
}
internal class WizardContainer : WebControl {
internal Control ControlToRender { get; set; }
protected internal override void Render(HtmlTextWriter writer) {
if (ControlToRender == null) {
RenderChildren(writer);
} else {
ControlToRender.Render(writer);
}
}
}
}
internal class TableWizardRendering : WizardRenderingBase {
private const string _headerCellID = "HeaderContainer";
private const string _sideBarCellID = "SideBarContainer";
private const string _stepTableCellID = "StepTableCell";
private TableCell _headerTableCell;
private TableRow _headerTableRow;
private TableRow _navigationRow;
private TableCell _navigationTableCell;
private Table _renderTable;
private TableCell _stepTableCell;
private LiteralControl _titleLiteral;
public TableWizardRendering(Wizard wizard)
: base(wizard) {
}
// Returns the cell which the navigation template container should be added to
private TableCell NavigationTableCell {
get {
if (_navigationTableCell == null) {
_navigationTableCell = new TableCell();
}
return _navigationTableCell;
}
}
public override void ApplyControlProperties() {
// Nothing to do if the Wizard is empty;
// Apply the control properties at designtime so that controls inside templates are styled properly.
if (!Owner.DesignMode &&
(Owner.ActiveStepIndex < 0 || Owner.ActiveStepIndex >= Owner.WizardSteps.Count || Owner.WizardSteps.Count == 0)) {
return;
}
if (Owner.SideBarEnabled && Owner._sideBarStyle != null) {
// Apply Sidebar style on the table cell VSWhidbey 377064
Owner._sideBarTableCell.ApplyStyle(Owner._sideBarStyle);
}
ApplyControlProperties_Header();
ApplyControlProperties_WizardSteps();
ApplyControlProperties_Navigation();
ApplyControlProperties_Sidebar();
if (_renderTable != null) {
// Clear out the accesskey/tab index so it doesn't get applied to the tables in the container
Util.CopyBaseAttributesToInnerControl(Owner, _renderTable);
if (Owner.ControlStyleCreated) {
_renderTable.ApplyStyle(Owner.ControlStyle);
} else {
// initialize defaults that are different from TableStyle
_renderTable.CellSpacing = 0;
_renderTable.CellPadding = 0;
}
// On Mac IE, if height is not set, render height:1px, so the table sizes to contents.
// Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
if (!Owner.DesignMode && Owner.IsMacIE5 &&
(!Owner.ControlStyleCreated || Owner.ControlStyle.Height == Unit.Empty)) {
_renderTable.ControlStyle.Height = Unit.Pixel(1);
}
}
// On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
// Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
if (!Owner.DesignMode && _navigationTableCell != null && Owner.IsMacIE5) {
_navigationTableCell.ControlStyle.Height = Unit.Pixel(1);
}
}
private void ApplyControlProperties_Navigation() {
ApplyNavigationTemplateProperties();
ApplyCustomNavigationTemplateProperties();
if (_navigationTableCell != null) {
NavigationTableCell.HorizontalAlign = HorizontalAlign.Right;
// Copy the styles from the StepStyle property if defined.
if (Owner._navigationStyle != null) {
if (!Owner.DesignMode && Owner.IsMacIE5 && Owner._navigationStyle.Height == Unit.Empty) {
Owner._navigationStyle.Height = Unit.Pixel(1);
}
_navigationTableCell.ApplyStyle(Owner._navigationStyle);
}
}
if (Owner.ShowCustomNavigationTemplate) {
// Make sure the navigation row is visible
_navigationRow.Visible = true;
}
}
private void ApplyControlProperties_WizardSteps() {
// Apply the WizardSteps style
if (_stepTableCell != null) {
// Copy the styles from the StepStyle property if defined.
if (Owner._stepStyle != null) {
if (!Owner.DesignMode && Owner.IsMacIE5 && Owner._stepStyle.Height == Unit.Empty) {
Owner._stepStyle.Height = Unit.Pixel(1);
}
_stepTableCell.ApplyStyle(Owner._stepStyle);
}
}
}
private void ApplyControlProperties_Header() {
if (_headerTableRow != null) {
// If headerTemplate is not defined and headertext is empty, do not render the
// empty table row.
if ((Owner.HeaderTemplate == null) && String.IsNullOrEmpty(Owner.HeaderText)) {
_headerTableRow.Visible = false;
} else {
_headerTableCell.ApplyStyle(Owner._headerStyle);
// if HeaderTemplate is defined.
if (Owner.HeaderTemplate != null) {
if (_titleLiteral != null) {
_titleLiteral.Visible = false;
}
}
// Otherwise HeaderText is defined.
else {
Debug.Assert(Owner.HeaderText != null && Owner.HeaderText.Length > 0);
if (_titleLiteral != null) {
_titleLiteral.Text = Owner.HeaderText;
}
}
}
}
}
protected override WizardStepType SetActiveTemplates() {
WizardStepType type = base.SetActiveTemplates();
if (type != WizardStepType.Complete) {
// Only render sidebartablecell if necessary
if (Owner._sideBarTableCell != null) {
Owner._sideBarTableCell.Visible = Owner.SideBarEnabled && Owner._renderSideBarDataList;
}
}
return type;
}
public override void OnlyShowCompleteStep() {
// Do not render header or sidebarlist in complete steps;
if (_headerTableRow != null) {
_headerTableRow.Visible = false;
}
if (Owner._sideBarTableCell != null) {
Owner._sideBarTableCell.Visible = false;
}
_navigationRow.Visible = false;
}
public override void CreateControlHierarchy() {
// Use the inner table to render header template, step and navigation template
Table mainContentTable = null;
if (Owner.DisplaySideBar) {
mainContentTable = CreateControlHierarchy_CreateLayoutWithSideBar();
} else {
mainContentTable = CreateControlHierarchy_CreateLayoutWithoutSideBar();
}
CreateControlHierarchy_CreateHeaderArea(mainContentTable);
CreateControlHierarchy_CreateStepArea(mainContentTable);
CreateControlHierarchy_CreateNavigationArea(mainContentTable);
}
private void CreateControlHierarchy_CreateNavigationArea(Table mainContentTable) {
_navigationRow = new TableRow();
mainContentTable.Controls.Add(_navigationRow);
_navigationRow.Controls.Add(NavigationTableCell);
CreateNavigationControlHierarchy(NavigationTableCell);
}
private void CreateControlHierarchy_CreateStepArea(Table mainContentTable) {
TableRow stepRow = new TableRow() {
// The step row needs to use the most of the table size.
Height = Unit.Percentage(100)
};
mainContentTable.Controls.Add(stepRow);
_stepTableCell = new TableCell();
stepRow.Controls.Add(_stepTableCell);
_stepTableCell.Controls.Add(Owner.MultiView);
Owner.InstantiateStepContentTemplates();
}
private void CreateControlHierarchy_CreateHeaderArea(Table mainContentTable) {
_headerTableRow = new TableRow();
mainContentTable.Controls.Add(_headerTableRow);
_headerTableCell = new InternalTableCell(Owner) {
ID = _headerCellID
};
if (Owner.HeaderTemplate != null) {
_headerTableCell.EnableTheming = Owner.EnableTheming;
Owner.HeaderTemplate.InstantiateIn(_headerTableCell);
} else {
// Render the title property if HeaderTemplate is not defined.
_titleLiteral = new LiteralControl();
_headerTableCell.Controls.Add(_titleLiteral);
}
_headerTableRow.Controls.Add(_headerTableCell);
}
private Table CreateControlHierarchy_CreateLayoutWithoutSideBar() {
// if sidebar is disabled, add mainContentTable directly into the Wizard control.
var mainContentTable = new WizardChildTable(Owner) {
EnableTheming = false
};
using (new WizardControlCollectionModifier(Owner)) {
Owner.Controls.Add(mainContentTable);
}
_renderTable = mainContentTable;
return mainContentTable;
}
private Table CreateControlHierarchy_CreateLayoutWithSideBar() {
// Create an outer table and make all child controls into the right cell.
// Use the left cell to render the side bar.
Table outerTable = new WizardChildTable(Owner) {
EnableTheming = false
};
TableRow outerRow = new TableRow();
outerTable.Controls.Add(outerRow);
// Use the existing sideBarTableCell if possible.
TableCell outerLeftCell = Owner._sideBarTableCell ?? CreateControlHierarchy_CreateSideBarTableCell();
outerRow.Controls.Add(outerLeftCell);
Owner._sideBarTableCell = outerLeftCell;
Owner._renderSideBarDataList = false;
// Right cell is used for header, step and navigation areas.
TableCell outerRightCell = new TableCell() {
// Maximize the inner default table Whidbey 143409.
Height = Unit.Percentage(100)
};
outerRow.Controls.Add(outerRightCell);
var mainContentTable = new WizardDefaultInnerTable() {
CellSpacing = 0,
Height = Unit.Percentage(100),
Width = Unit.Percentage(100)
};
outerRightCell.Controls.Add(mainContentTable);
// On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
// Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
if (!Owner.DesignMode && Owner.IsMacIE5) {
outerRightCell.Height = Unit.Pixel(1);
}
// Add the table into the Wizard control
using (new WizardControlCollectionModifier(Owner)) {
Owner.Controls.Add(outerTable);
}
CreateControlHierarchy_CleanUpOldSideBarList(Owner.SideBarList);
Owner._sideBarList = CreateControlHierarchy_SetUpSideBarList(Owner._sideBarTableCell);
_renderTable = outerTable;
return mainContentTable;
}
private TableCell CreateControlHierarchy_CreateSideBarTableCell() {
// Left cell is used for SideBar
TableCell outerLeftCell = new AccessibleTableCell(Owner) {
ID = _sideBarCellID,
// Left cell should expand to all height if sidebar is displayed.
Height = Unit.Percentage(100)
};
ITemplate sideBarTemplate = Owner.SideBarTemplate;
if (sideBarTemplate == null) {
outerLeftCell.EnableViewState = false;
sideBarTemplate = Owner.CreateDefaultSideBarTemplate();
} else {
outerLeftCell.EnableTheming = Owner.EnableTheming;
}
sideBarTemplate.InstantiateIn(outerLeftCell);
return outerLeftCell;
}
public override void SetDesignModeState(IDictionary dictionary) {
base.SetDesignModeState(dictionary);
dictionary[_stepTableCellID] = _stepTableCell;
}
}
#endregion
private class WizardControlCollection : ControlCollection {
public WizardControlCollection(Wizard wizard)
: base(wizard) {
if (!wizard.DesignMode)
SetCollectionReadOnly(SR.Wizard_Cannot_Modify_ControlCollection);
}
}
private class WizardControlCollectionModifier : IDisposable {
Wizard _wizard;
ControlCollection _controls;
String _originalError;
public WizardControlCollectionModifier(Wizard wizard) {
_wizard = wizard;
if (!_wizard.DesignMode) {
// Remember the ControlCollection so we don't need to access the
// Controls property by GC during Dispose. Accessing this property has the
// side-effect of creating the entire child controls on CompositeControl.
_controls = _wizard.Controls;
_originalError = _controls.SetCollectionReadOnly(null);
}
}
void IDisposable.Dispose() {
if (!_wizard.DesignMode) {
_controls.SetCollectionReadOnly(_originalError);
}
}
}
[SupportsEventValidation]
private class WizardChildTable : ChildTable {
private Wizard _owner;
internal WizardChildTable(Wizard owner) {
_owner = owner;
}
protected override bool OnBubbleEvent(object source, EventArgs args) {
return _owner.OnBubbleEvent(source, args);
}
}
private enum WizardTemplateType {
StartNavigationTemplate = 0,
StepNavigationTemplate = 1,
FinishNavigationTemplate = 2,
}
private sealed class NavigationTemplate : ITemplate {
private Wizard _wizard;
private WizardTemplateType _templateType;
private String _button1ID;
private String _button2ID;
private String _button3ID;
private const string _startNextButtonID = "StartNext";
private const string _stepNextButtonID = "StepNext";
private const string _stepPreviousButtonID = "StepPrevious";
private const string _finishPreviousButtonID = "FinishPrevious";
private const string _finishButtonID = "Finish";
private const string _cancelButtonID = "Cancel";
private TableRow _row;
private IButtonControl[][] _buttons;
private bool _button1CausesValidation;
internal static NavigationTemplate GetDefaultStartNavigationTemplate(Wizard wizard) {
return new NavigationTemplate(wizard, WizardTemplateType.StartNavigationTemplate,
true, null, _startNextButtonID, _cancelButtonID);
}
internal static NavigationTemplate GetDefaultStepNavigationTemplate(Wizard wizard) {
return new NavigationTemplate(wizard, WizardTemplateType.StepNavigationTemplate,
false, _stepPreviousButtonID, _stepNextButtonID, _cancelButtonID);
}
internal static NavigationTemplate GetDefaultFinishNavigationTemplate(Wizard wizard) {
return new NavigationTemplate(wizard, WizardTemplateType.FinishNavigationTemplate,
false, _finishPreviousButtonID, _finishButtonID, _cancelButtonID);
}
internal void ResetButtonsVisibility() {
Debug.Assert(_wizard.DesignMode);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
Control c = _buttons[i][j] as Control;
if (c != null) c.Visible = false;
}
}
}
private NavigationTemplate(Wizard wizard, WizardTemplateType templateType, bool button1CausesValidation,
String label1ID, String label2ID, String label3ID) {
_wizard = wizard;
_button1ID = label1ID;
_button2ID = label2ID;
_button3ID = label3ID;
_templateType = templateType;
_buttons = new IButtonControl[3][];
_buttons[0] = new IButtonControl[3];
_buttons[1] = new IButtonControl[3];
_buttons[2] = new IButtonControl[3];
_button1CausesValidation = button1CausesValidation;
}
void ITemplate.InstantiateIn(Control container) {
Table table = new WizardDefaultInnerTable();
// Increase the default space and padding so the layout
// of the buttons look good. Also, to make custom border
// visible. VSWhidbey 377069
table.CellSpacing = 5;
table.CellPadding = 5;
container.Controls.Add(table);
_row = new TableRow();
table.Rows.Add(_row);
if (_button1ID != null) {
CreateButtonControl(_buttons[0], _button1ID, _button1CausesValidation,
MovePreviousCommandName);
}
if (_button2ID != null) {
CreateButtonControl(_buttons[1], _button2ID, true /* causesValidation */,
_templateType == WizardTemplateType.FinishNavigationTemplate ? MoveCompleteCommandName : MoveNextCommandName);
}
CreateButtonControl(_buttons[2], _button3ID, false /* causesValidation */, CancelCommandName);
}
private void OnPreRender(object source, EventArgs e) {
((ImageButton)source).Visible = false;
}
private void CreateButtonControl(IButtonControl[] buttons, String id, bool causesValidation, string commandName) {
LinkButton linkButton = new LinkButton();
linkButton.CausesValidation = causesValidation;
linkButton.ID = id + "LinkButton";
linkButton.Visible = false;
linkButton.CommandName = commandName;
linkButton.TabIndex = _wizard.TabIndex;
_wizard.RegisterCommandEvents(linkButton);
buttons[0] = linkButton;
ImageButton imageButton = new ImageButton();
imageButton.CausesValidation = causesValidation;
imageButton.ID = id + "ImageButton";
imageButton.Visible = true;
imageButton.CommandName = commandName;
imageButton.TabIndex = _wizard.TabIndex;
_wizard.RegisterCommandEvents(imageButton);
imageButton.PreRender += new EventHandler(OnPreRender);
buttons[1] = imageButton;
Button button = new Button();
button.CausesValidation = causesValidation;
button.ID = id + "Button";
button.Visible = false;
button.CommandName = commandName;
button.TabIndex = _wizard.TabIndex;
_wizard.RegisterCommandEvents(button);
buttons[2] = button;
TableCell tableCell = new TableCell();
tableCell.HorizontalAlign = HorizontalAlign.Right;
_row.Cells.Add(tableCell);
tableCell.Controls.Add(linkButton);
tableCell.Controls.Add(imageButton);
tableCell.Controls.Add(button);
}
internal IButtonControl FirstButton {
get {
ButtonType buttonType = ButtonType.Button;
switch (_templateType) {
case WizardTemplateType.StartNavigationTemplate:
Debug.Fail("Invalid template/button type");
break;
case WizardTemplateType.StepNavigationTemplate:
buttonType = _wizard.StepPreviousButtonType;
break;
case WizardTemplateType.FinishNavigationTemplate:
default:
buttonType = _wizard.FinishPreviousButtonType;
break;
}
return GetButtonBasedOnType(0, buttonType);
}
}
internal IButtonControl SecondButton {
get {
ButtonType buttonType = ButtonType.Button;
switch (_templateType) {
case WizardTemplateType.StartNavigationTemplate:
buttonType = _wizard.StartNextButtonType;
break;
case WizardTemplateType.StepNavigationTemplate:
buttonType = _wizard.StepNextButtonType;
break;
case WizardTemplateType.FinishNavigationTemplate:
default:
buttonType = _wizard.FinishCompleteButtonType;
break;
}
return GetButtonBasedOnType(1, buttonType);
}
}
internal IButtonControl CancelButton {
get {
ButtonType buttonType = _wizard.CancelButtonType;
return GetButtonBasedOnType(2, buttonType);
}
}
private IButtonControl GetButtonBasedOnType(int pos, ButtonType type) {
switch (type) {
case ButtonType.Button:
return _buttons[pos][2];
case ButtonType.Image:
return _buttons[pos][1];
case ButtonType.Link:
return _buttons[pos][0];
}
return null;
}
}
private class DataListItemTemplate : ITemplate {
Wizard _owner;
internal DataListItemTemplate(Wizard owner) {
_owner = owner;
}
public void InstantiateIn(Control container) {
LinkButton linkButton = new LinkButton();
container.Controls.Add(linkButton);
linkButton.ID = SideBarButtonID;
if (_owner.DesignMode) {
linkButton.MergeStyle(_owner.SideBarButtonStyle);
}
}
}
private class DefaultSideBarTemplate : ITemplate {
private Wizard _owner;
internal DefaultSideBarTemplate(Wizard owner) {
_owner = owner;
}
public void InstantiateIn(Control container) {
Control sideBarListControl = null;
if (_owner.SideBarList == null) {
var dataList = new DataList();
dataList.ID = Wizard.DataListID;
dataList.SelectedItemStyle.Font.Bold = true;
dataList.ItemTemplate = _owner.CreateDefaultDataListItemTemplate();
sideBarListControl = dataList;
} else {
sideBarListControl = (Control)_owner.SideBarList;
}
container.Controls.Add(sideBarListControl);
}
}
// Internally use an empty table (with a row and a cell) to render the content.
internal abstract class BlockControl : WebControl, INamingContainer, INonBindingContainer {
private Table _table;
internal TableCell _cell;
internal Wizard _owner;
internal BlockControl(Wizard owner) {
Debug.Assert(owner != null);
_owner = owner;
_table = new WizardDefaultInnerTable();
_table.EnableTheming = false;
Controls.Add(_table);
TableRow row = new TableRow();
_table.Controls.Add(row);
_cell = new TableCell();
_cell.Height = Unit.Percentage(100);
_cell.Width = Unit.Percentage(100);
row.Controls.Add(_cell);
HandleMacIECellHeight();
PreventAutoID();
}
protected Table Table {
get { return _table; }
}
internal TableCell InnerCell {
get { return _cell; }
}
protected override Style CreateControlStyle() {
return new TableItemStyle(ViewState);
}
public override void Focus() {
throw new NotSupportedException(SR.GetString(SR.NoFocusSupport, this.GetType().Name));
}
internal void HandleMacIECellHeight() {
// On Mac IE, render height:1px of the inner table cell, so the table sizes to contents.
// Otherwise, Mac IE may give the table an arbitrary height (equal to the width of its contents).
if (!_owner.DesignMode && _owner.IsMacIE5) {
_cell.Height = Unit.Pixel(1);
}
}
// Renders the inner control only
protected internal override void Render(HtmlTextWriter writer) {
RenderContents(writer);
}
internal void SetEnableTheming() {
_cell.EnableTheming = _owner.EnableTheming;
}
}
private class InternalTableCell : TableCell, INamingContainer, INonBindingContainer {
protected Wizard _owner;
internal InternalTableCell(Wizard owner) {
_owner = owner;
}
// Do not render any attributes other than Style on this cell.
protected override void AddAttributesToRender(HtmlTextWriter writer) {
if (ControlStyleCreated && !ControlStyle.IsEmpty) {
// let the style add attributes
ControlStyle.AddAttributesToRender(writer, this);
}
}
}
private class AccessibleTableCell : InternalTableCell {
internal AccessibleTableCell(Wizard owner)
: base(owner) {
}
protected internal override void RenderChildren(HtmlTextWriter writer) {
ControlRenderingHelper.WriteSkipLinkStart(writer, RenderingCompatibility, _owner.DesignMode, _owner.SkipLinkText, SpacerImageUrl, _owner.ClientID);
base.RenderChildren(writer);
ControlRenderingHelper.WriteSkipLinkEnd(writer, _owner.DesignMode, _owner.SkipLinkText, _owner.ClientID);
}
}
internal class BaseContentTemplateContainer : BlockControl {
private bool _useInnerTable;
internal BaseContentTemplateContainer(Wizard owner, bool useInnerTable)
: base(owner) {
_useInnerTable = useInnerTable;
if (useInnerTable) {
// Set the table width to 100% so the table within each
// row will have the same width. VSWhidbey 377182
Table.Width = Unit.Percentage(100);
Table.Height = Unit.Percentage(100);
}
else {
// remove nested table from Control tree
Controls.Clear();
}
}
internal void AddChildControl(Control c) {
Container.Controls.Add(c);
}
internal Control Container {
get {
return _useInnerTable ? InnerCell : (Control)this;
}
}
}
#region Navigation Template Containers
internal class BaseNavigationTemplateContainer : WebControl, INamingContainer, INonBindingContainer {
private IButtonControl _finishButton;
private IButtonControl _previousButton;
private IButtonControl _nextButton;
private IButtonControl _cancelButton;
private Wizard _owner;
internal BaseNavigationTemplateContainer(Wizard owner) {
_owner = owner;
}
internal Wizard Owner {
get {
return _owner;
}
}
internal void ApplyButtonStyle(Style finishStyle, Style prevStyle, Style nextStyle, Style cancelStyle) {
if (FinishButton != null) ApplyButtonStyleInternal(FinishButton, finishStyle);
if (PreviousButton != null) ApplyButtonStyleInternal(PreviousButton, prevStyle);
if (NextButton != null) ApplyButtonStyleInternal(NextButton, nextStyle);
if (CancelButton != null) ApplyButtonStyleInternal(CancelButton, cancelStyle);
}
protected void ApplyButtonStyleInternal(IButtonControl control, Style buttonStyle) {
WebControl webCtrl = control as WebControl;
if (webCtrl != null) {
webCtrl.ApplyStyle(buttonStyle);
webCtrl.ControlStyle.MergeWith(Owner.NavigationButtonStyle);
}
}
public override void Focus() {
throw new NotSupportedException(SR.GetString(SR.NoFocusSupport, this.GetType().Name));
}
internal void RegisterButtonCommandEvents() {
Owner.RegisterCommandEvents(NextButton);
Owner.RegisterCommandEvents(FinishButton);
Owner.RegisterCommandEvents(PreviousButton);
Owner.RegisterCommandEvents(CancelButton);
}
internal IButtonControl CancelButton {
get {
if (_cancelButton != null) {
return _cancelButton;
}
_cancelButton = FindControl(Wizard.CancelButtonID) as IButtonControl;
return _cancelButton;
}
set {
_cancelButton = value;
}
}
internal virtual IButtonControl NextButton {
get {
if (_nextButton != null) {
return _nextButton;
}
_nextButton = FindControl(Wizard.StepNextButtonID) as IButtonControl;
return _nextButton;
}
set {
_nextButton = value;
}
}
internal virtual IButtonControl PreviousButton {
get {
if (_previousButton != null) {
return _previousButton;
}
_previousButton = FindControl(Wizard.StepPreviousButtonID) as IButtonControl;
return _previousButton;
}
set {
_previousButton = value;
}
}
internal IButtonControl FinishButton {
get {
if (_finishButton != null) {
return _finishButton;
}
_finishButton = FindControl(Wizard.FinishButtonID) as IButtonControl;
return _finishButton;
}
set {
_finishButton = value;
}
}
internal void SetEnableTheming() {
this.EnableTheming = _owner.EnableTheming;
}
// Renders the inner control only
protected internal override void Render(HtmlTextWriter writer) {
RenderContents(writer);
}
}
private class FinishNavigationTemplateContainer : BaseNavigationTemplateContainer {
private IButtonControl _previousButton;
internal FinishNavigationTemplateContainer(Wizard owner)
: base(owner) {
}
internal override IButtonControl PreviousButton {
get {
if (_previousButton != null) {
return _previousButton;
}
_previousButton = FindControl(Wizard.FinishPreviousButtonID) as IButtonControl;
return _previousButton;
}
set {
_previousButton = value;
}
}
}
private class StartNavigationTemplateContainer : BaseNavigationTemplateContainer {
private IButtonControl _nextButton;
internal StartNavigationTemplateContainer(Wizard owner)
: base(owner) {
}
internal override IButtonControl NextButton {
get {
if (_nextButton != null) {
return _nextButton;
}
_nextButton = FindControl(Wizard.StartNextButtonID) as IButtonControl;
return _nextButton;
}
set {
_nextButton = value;
}
}
}
private class StepNavigationTemplateContainer : BaseNavigationTemplateContainer {
internal StepNavigationTemplateContainer(Wizard owner)
: base(owner) {
}
}
#endregion
}
public sealed class WizardStepCollection : IList {
private Wizard _wizard;
internal WizardStepCollection(Wizard wizard) {
this._wizard = wizard;
wizard.TemplatedSteps.Clear();
}
public int Count {
get {
return Views.Count;
}
}
public bool IsReadOnly {
get {
return Views.IsReadOnly;
}
}
public bool IsSynchronized {
get {
return false;
}
}
public object SyncRoot {
get {
return this;
}
}
private ViewCollection Views {
get {
return _wizard.MultiView.Views;
}
}
public WizardStepBase this[int index] {
get {
return (WizardStepBase)Views[index];
}
}
public void Add(WizardStepBase wizardStep) {
//
if (wizardStep == null) {
throw new ArgumentNullException("wizardStep");
}
wizardStep.PreventAutoID();
RemoveIfAlreadyExistsInWizard(wizardStep);
wizardStep.Owner = _wizard;
Views.Add(wizardStep);
AddTemplatedWizardStep(wizardStep);
NotifyWizardStepsChanged();
}
public void AddAt(int index, WizardStepBase wizardStep) {
if (wizardStep == null) {
throw new ArgumentNullException("wizardStep");
}
RemoveIfAlreadyExistsInWizard(wizardStep);
wizardStep.PreventAutoID();
wizardStep.Owner = _wizard;
Views.AddAt(index, wizardStep);
AddTemplatedWizardStep(wizardStep);
NotifyWizardStepsChanged();
}
private void AddTemplatedWizardStep(WizardStepBase wizardStep) {
var templatedWizardStep = wizardStep as TemplatedWizardStep;
if (templatedWizardStep != null) {
_wizard.TemplatedSteps.Add(templatedWizardStep);
_wizard.RegisterCustomNavigationContainers(templatedWizardStep);
}
}
public void Clear() {
Views.Clear();
_wizard.TemplatedSteps.Clear();
NotifyWizardStepsChanged();
}
public bool Contains(WizardStepBase wizardStep) {
if (wizardStep == null) {
throw new ArgumentNullException("wizardStep");
}
return Views.Contains(wizardStep);
}
public void CopyTo(WizardStepBase[] array, int index) {
Views.CopyTo(array, index);
}
public IEnumerator GetEnumerator() {
return Views.GetEnumerator();
}
public int IndexOf(WizardStepBase wizardStep) {
if (wizardStep == null) {
throw new ArgumentNullException("wizardStep");
}
return Views.IndexOf(wizardStep);
}
public void Insert(int index, WizardStepBase wizardStep) {
AddAt(index, wizardStep);
}
internal void NotifyWizardStepsChanged() {
_wizard.OnWizardStepsChanged();
}
public void Remove(WizardStepBase wizardStep) {
if (wizardStep == null) {
throw new ArgumentNullException("wizardStep");
}
Views.Remove(wizardStep);
wizardStep.Owner = null;
var templatedWizardStep = wizardStep as TemplatedWizardStep;
if (templatedWizardStep != null) {
_wizard.TemplatedSteps.Remove(templatedWizardStep);
}
NotifyWizardStepsChanged();
}
public void RemoveAt(int index) {
WizardStepBase wizardStep = Views[index] as WizardStepBase;
if (wizardStep != null) {
wizardStep.Owner = null;
var templatedWizardStep = wizardStep as TemplatedWizardStep;
if (templatedWizardStep != null) {
_wizard.TemplatedSteps.Remove(templatedWizardStep);
}
}
Views.RemoveAt(index);
NotifyWizardStepsChanged();
}
private static void RemoveIfAlreadyExistsInWizard(WizardStepBase wizardStep) {
if (wizardStep.Owner != null) {
wizardStep.Owner.WizardSteps.Remove(wizardStep);
}
}
private static WizardStepBase GetStepAndVerify(object value) {
WizardStepBase step = value as WizardStepBase;
if (step == null)
throw new ArgumentException(SR.GetString(SR.Wizard_WizardStepOnly));
return step;
}
#region ICollection implementation
/// <internalonly/>
void ICollection.CopyTo(Array array, int index) {
Views.CopyTo(array, index);
}
#endregion //ICollection implementation
#region IList implementation
/// <internalonly/>
bool IList.IsFixedSize {
get {
return false;
}
}
/// <internalonly/>
object IList.this[int index] {
get {
return Views[index];
}
set {
RemoveAt(index);
AddAt(index, GetStepAndVerify(value));
}
}
/// <internalonly/>
int IList.Add(object value) {
WizardStepBase step = GetStepAndVerify(value);
step.PreventAutoID();
Add(step);
return IndexOf(step);
}
/// <internalonly/>
bool IList.Contains(object value) {
return Contains(GetStepAndVerify(value));
}
/// <internalonly/>
int IList.IndexOf(object value) {
return IndexOf(GetStepAndVerify(value));
}
/// <internalonly/>
void IList.Insert(int index, object value) {
AddAt(index, GetStepAndVerify(value));
}
/// <internalonly/>
void IList.Remove(object value) {
Remove(GetStepAndVerify(value));
}
#endregion // IList implementation
}
[SupportsEventValidation]
internal class WizardDefaultInnerTable : Table {
internal WizardDefaultInnerTable() {
PreventAutoID();
// cell padding and spacing should be 0 since these tables are for internal layout only.
CellPadding = 0;
CellSpacing = 0;
}
}
public class WizardNavigationEventArgs : EventArgs {
private int _currentStepIndex;
private int _nextStepIndex;
private bool _cancel;
public WizardNavigationEventArgs(int currentStepIndex, int nextStepIndex) {
_currentStepIndex = currentStepIndex;
_nextStepIndex = nextStepIndex;
}
public bool Cancel {
get {
return _cancel;
}
set {
_cancel = value;
}
}
public int CurrentStepIndex {
get {
return _currentStepIndex;
}
}
public int NextStepIndex {
get {
return _nextStepIndex;
}
}
internal void SetNextStepIndex(int nextStepIndex) {
_nextStepIndex = nextStepIndex;
}
}
public delegate void WizardNavigationEventHandler(object sender, WizardNavigationEventArgs e);
}
|