using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
namespace Gui.Wizard
{
/// <summary>
/// A wizard is the control added to a form to provide a step by step functionality.
/// It contains <see cref="WizardPage"/>s in the <see cref="Pages"/> collection, which
/// are containers for other controls. Only one wizard page is shown at a time in the client
/// are of the wizard.
/// </summary>
[Designer(typeof(Gui.Wizard.WizardDesigner))]
[ToolboxItem(true)]
[ToolboxBitmap(typeof(Gui.Wizard.Wizard))]
public class Wizard : System.Windows.Forms.UserControl
{
protected internal System.Windows.Forms.Panel pnlButtons;
private System.Windows.Forms.Panel pnlButtonBright3d;
private System.Windows.Forms.Panel pnlButtonDark3d;
protected internal System.Windows.Forms.Button btnBack;
protected internal System.Windows.Forms.Button btnNext;
private System.Windows.Forms.Button btnCancel;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
/// <summary>
/// Wizard control with designer support
/// </summary>
public Wizard()
{
//Empty collection of Pages
vPages = new PageCollection(this);
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
private void Wizard_Load(object sender, System.EventArgs e)
{
//Attempt to activate a page
ActivatePage(0);
//Can I add my self as default cancel button
Form form = this.FindForm();
if (form != null && DesignMode == false)
form.CancelButton = btnCancel;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pnlButtons = new System.Windows.Forms.Panel();
this.btnCancel = new System.Windows.Forms.Button();
this.btnNext = new System.Windows.Forms.Button();
this.btnBack = new System.Windows.Forms.Button();
this.pnlButtonBright3d = new System.Windows.Forms.Panel();
this.pnlButtonDark3d = new System.Windows.Forms.Panel();
this.pnlButtons.SuspendLayout();
this.SuspendLayout();
//
// pnlButtons
//
this.pnlButtons.Controls.Add(this.btnCancel);
this.pnlButtons.Controls.Add(this.btnNext);
this.pnlButtons.Controls.Add(this.btnBack);
this.pnlButtons.Controls.Add(this.pnlButtonBright3d);
this.pnlButtons.Controls.Add(this.pnlButtonDark3d);
this.pnlButtons.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pnlButtons.Location = new System.Drawing.Point(0, 224);
this.pnlButtons.Name = "pnlButtons";
this.pnlButtons.Size = new System.Drawing.Size(444, 48);
this.pnlButtons.TabIndex = 0;
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnCancel.Location = new System.Drawing.Point(356, 12);
this.btnCancel.Name = "btnCancel";
this.btnCancel.TabIndex = 5;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnNext
//
this.btnNext.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnNext.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnNext.Location = new System.Drawing.Point(272, 12);
this.btnNext.Name = "btnNext";
this.btnNext.TabIndex = 4;
this.btnNext.Text = "&Next >";
this.btnNext.Click += new System.EventHandler(this.btnNext_Click);
this.btnNext.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnNext_MouseDown);
//
// btnBack
//
this.btnBack.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnBack.Location = new System.Drawing.Point(196, 12);
this.btnBack.Name = "btnBack";
this.btnBack.TabIndex = 3;
this.btnBack.Text = "< &Back";
this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
this.btnBack.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnBack_MouseDown);
//
// pnlButtonBright3d
//
this.pnlButtonBright3d.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.pnlButtonBright3d.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlButtonBright3d.Location = new System.Drawing.Point(0, 1);
this.pnlButtonBright3d.Name = "pnlButtonBright3d";
this.pnlButtonBright3d.Size = new System.Drawing.Size(444, 1);
this.pnlButtonBright3d.TabIndex = 1;
//
// pnlButtonDark3d
//
this.pnlButtonDark3d.BackColor = System.Drawing.SystemColors.ControlDark;
this.pnlButtonDark3d.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlButtonDark3d.Location = new System.Drawing.Point(0, 0);
this.pnlButtonDark3d.Name = "pnlButtonDark3d";
this.pnlButtonDark3d.Size = new System.Drawing.Size(444, 1);
this.pnlButtonDark3d.TabIndex = 2;
//
// Wizard
//
this.Controls.Add(this.pnlButtons);
this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.Name = "Wizard";
this.Size = new System.Drawing.Size(444, 272);
this.Load += new System.EventHandler(this.Wizard_Load);
this.pnlButtons.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private PageCollection vPages;
/// <summary>
/// Returns the collection of Pages in the wizard
/// </summary>
[Category("Wizard")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public PageCollection Pages
{
get
{
return vPages;
}
}
private WizardPage vActivePage = null;
/// <summary>
/// Gets/Sets the activePage in the wizard
/// </summary>
[Category("Wizard")]
internal int PageIndex
{
get
{
return vPages.IndexOf(vActivePage);
}
set
{
//Do I have any pages?
if(vPages.Count == 0)
{
//No then show nothing
ActivatePage(-1);
return;
}
// Validate the page asked for
if (value < -1 || value >= vPages.Count)
{
throw new ArgumentOutOfRangeException("PageIndex",
value,
"The page index must be between 0 and "+Convert.ToString(vPages.Count-1)
);
}
//Select the new page
ActivatePage(value);
}
}
/// <summary>
/// Alternative way of getting/Setiing the current page by using wizardPage objects
/// </summary>
public WizardPage Page
{
get
{
return vActivePage;
}
//Dont use this anymore, see Next, Back, NextTo and BackTo
// set
// {
// ActivatePage(value);
// }
}
protected internal void ActivatePage(int index)
{
//If the new page is invalid
if (index <0 || index >= vPages.Count)
{
btnNext.Enabled = false;
btnBack.Enabled = false;
return;
}
//Change to the new Page
WizardPage tWizPage = ((WizardPage) vPages[index]);
//Really activate the page
ActivatePage(tWizPage);
}
protected internal void ActivatePage(WizardPage page)
{
//Deactivate the current
if (vActivePage != null)
{
vActivePage.Visible = false;
}
//Activate the new page
vActivePage = page;
if (vActivePage != null)
{
//Ensure that this panel displays inside the wizard
vActivePage.Parent = this;
if (this.Contains(vActivePage) == false)
{
this.Container.Add(vActivePage);
}
//Make it fill the space
vActivePage.Dock = DockStyle.Fill;
vActivePage.Visible = true;
vActivePage.BringToFront();
vActivePage.FocusFirstTabIndex();
}
//What should the back button say
if (this.PageIndex > 0)
{
btnBack.Enabled = true;
}
else
{
btnBack.Enabled = false;
}
//What should the Next button say
if (vPages.IndexOf(vActivePage) < vPages.Count-1
&& vActivePage.IsFinishPage == false)
{
btnNext.Text = "&Next >";
btnNext.Enabled = true;
//Don't close the wizard :)
btnNext.DialogResult = DialogResult.None;
}
else
{
btnNext.Text = "Fi&nish";
//Dont allow a finish in designer
if (DesignMode == true
&& vPages.IndexOf(vActivePage) == vPages.Count-1)
{
btnNext.Enabled = false;
}
else
{
btnNext.Enabled = true;
//If Not in design mode then allow a close
btnNext.DialogResult = DialogResult.OK;
}
}
//Cause a refresh
if (vActivePage != null)
vActivePage.Invalidate();
else
this.Invalidate();
}
private void btnNext_Click(object sender, System.EventArgs e)
{
Next();
}
private void btnNext_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (DesignMode == true)
Next();
}
private void btnBack_Click(object sender, System.EventArgs e)
{
Back();
}
private void btnBack_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (DesignMode == true)
Back();
}
private void btnCancel_Click(object sender, System.EventArgs e)
{
CancelEventArgs arg = new CancelEventArgs();
//Throw the event out to subscribers
if (CloseFromCancel != null)
{
CloseFromCancel(this, arg);
}
//If nobody told me to cancel
if (arg.Cancel == false)
{
//Then we close the form
this.FindForm().Close();
}
}
/// <summary>
/// Gets/Sets the enabled state of the Next button.
/// </summary>
[Category("Wizard")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool NextEnabled
{
get
{
return btnNext.Enabled;
}
set
{
btnNext.Enabled = value;
}
}
/// <summary>
/// Gets/Sets the enabled state of the back button.
/// </summary>
[Category("Wizard")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool BackEnabled
{
get
{
return btnBack.Enabled;
}
set
{
btnBack.Enabled = value;
}
}
/// <summary>
/// Gets/Sets the enabled state of the cancel button.
/// </summary>
[Category("Wizard")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool CancelEnabled
{
get
{
return btnCancel.Enabled;
}
set
{
btnCancel.Enabled = value;
}
}
/// <summary>
/// Called when the cancel button is pressed, before the form is closed. Set e.Cancel to true if
/// you do not wish the cancel to close the wizard.
/// </summary>
public event CancelEventHandler CloseFromCancel;
/// <summary>
/// Closes the current page after a <see cref="WizardPage.CloseFromNext"/>, then moves to
/// the Next page and calls <see cref="WizardPage.ShowFromNext"/>
/// </summary>
public void Next()
{
Debug.Assert(this.PageIndex >=0,"Page Index was below 0");
//Tell the Application I just closed a Page
int newPage = vActivePage.OnCloseFromNext(this);
//Did I just press Finish instead of Next
if (this.PageIndex <vPages.Count -1
&& (vActivePage.IsFinishPage == false || DesignMode == true))
{
//No still going
ActivatePage(newPage);
//Tell the application, I have just shown a page
vActivePage.OnShowFromNext(this);
}
else
{
Debug.Assert(this.PageIndex < vPages.Count, "Error I've just gone past the finish",
"btnNext_Click tried to go to page "+Convert.ToString(this.PageIndex+1)
+", but I only have "+Convert.ToString(vPages.Count));
//yep Finish was pressed
if (DesignMode == false)
this.ParentForm.Close();
}
}
/// <summary>
/// Moves to the page given and calls <see cref="WizardPage.ShowFromNext"/>
/// </summary>
/// <remarks>Does NOT call <see cref="WizardPage.CloseFromNext"/> on the current page</remarks>
/// <param name="page"></param>
public void NextTo(WizardPage page)
{
//Since we have a page to go to, then there is no need to validate most of it
ActivatePage(page);
//Tell the application, I have just shown a page
vActivePage.OnShowFromNext(this);
}
/// <summary>
/// Closes the current page after a <see cref="WizardPage.CloseFromBack"/>, then moves to
/// the previous page and calls <see cref="WizardPage.ShowFromBack"/>
/// </summary>
public void Back()
{
Debug.Assert(this.PageIndex <vPages.Count,"Page Index was beyond Maximum pages");
//Can I press back
Debug.Assert(this.PageIndex>0 && this.PageIndex < vPages.Count,"Attempted to go back to a page that doesn't exist");
//Tell the application that I closed a page
int newPage = vActivePage.OnCloseFromBack(this);
ActivatePage(newPage);
//Tell the application I have shown a page
vActivePage.OnShowFromBack(this);
}
/// <summary>
/// Moves to the page given and calls <see cref="WizardPage.ShowFromBack"/>
/// </summary>
/// <remarks>Does NOT call <see cref="WizardPage.CloseFromBack"/> on the current page</remarks>
/// <param name="page"></param>
public void BackTo(WizardPage page)
{
//Since we have a page to go to, then there is no need to validate most of it
ActivatePage(page);
//Tell the application, I have just shown a page
vActivePage.OnShowFromNext(this);
}
#if DEBUG
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint (e);
if (DesignMode)
{
const string noPagesText = "No wizard pages inside the wizard.";
SizeF textSize = e.Graphics.MeasureString(noPagesText, this.Font);
RectangleF layout = new RectangleF( (this.Width- textSize.Width)/2,
(this.pnlButtons.Top-textSize.Height)/2,
textSize.Width, textSize.Height);
Pen dashPen = (Pen) SystemPens.GrayText.Clone();
dashPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
e.Graphics.DrawRectangle(dashPen,
this.Left+8, this.Top+8,
this.Width-17, this.pnlButtons.Top-17);
e.Graphics.DrawString(noPagesText,this.Font,new SolidBrush(SystemColors.GrayText) ,layout);
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize (e);
if (DesignMode)
{
this.Invalidate();
}
}
#endif
}
}