This post applies to Sitecore 5.3
It's really quite logical -
if you're writing your own wizards for sitecore they always look better if they are real sitecore wizards, so here's a quick tutorial on how to make your own.
We're gonna go thru this in
5 steps:
- Create a custom wizard sheer ui / xaml code
- Create the CodeBeside class for our wizard
- Create a Command that we can later use to launch it with
- Edit the Web.Config and Commands.Config file
- Create a context menu extension that launches our wizard
Still interested? well, let's start then!
Step 1: Wizard XML code
Create a folder somewhere beneath
\sitecore modules\shell where you're going to store the code to your new wizard. The sheer ui / xaml code for the wizard is built using Sitecores
WizardForm, WizardFormFirstPage, WizardFormPage & WizardFormLastPage controls so it'll look great and take advantage of all the existing features they provide, like intro & exit pages, navigation, events and so on.
here's the code:
<?xml version="1.0" encoding="utf-8" ?>
<control
xmlns:def="Definition"
xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense">
<ExampleWizard>
<WizardForm
CodeBeside="Interfolio.Examples.ExampleWizardForm,Interfolio.Examples">
<WizardFormFirstPage
ID="FirstPage" Icon="People/48x48/user1.png">
<Border
Class="scWizardWelcomeTitle">
<Literal Text="Example
Wizard"/>
</Border>
<Literal Text="This wizard
will help
you:"/>
<ul>
<li>
<Literal
Text="Create your own
wizard."/>
</li>
<li>
<Literal
Text="Understand the sitecore
wizard."/>
</li>
</ul>
</WizardFormFirstPage>
<WizardFormPage
ID="WizardPageOne" Header="Page 1" Text="Select one of the available options.
When done, click next to continue."
Icon="People/48x48/user1.png">
<WizardFormIndent>
<GridPanel
ID="FieldsAction" Columns="2" Width="100%"
CellPadding="2">
<Literal Text="I want to.."
GridPanel.NoWrap="true" Width="100%" />
<Combobox
ID="SelectActions" GridPanel.Width="100%"
Width="100%">
<ListItem ID="create" Header="Keep looking at
this example" Value="newsite" />
<ListItem ID="edit" Header="Do
something, somewhere else" Value="editsite" />
<ListItem
ID="delete" Header="Yeah, you get the idea.." Value="deletesite"
/>
</Combobox>
</GridPanel>
</WizardFormIndent>
</WizardFormPage>
<WizardFormPage
ID="WizardPageTwo" Header="Page 2" Text="Specify some information. Name needs to
be set before moving on. When done, click next to continue."
Icon="People/48x48/user1.png">
<WizardFormIndent>
<GridPanel
ID="FieldsInformation" Columns="2" Width="100%"
CellPadding="2">
<Literal Text="Name:"
GridPanel.NoWrap="true"/>
<Edit ID="Name" Width="100%"
Change="OnNameChanged" GridPanel.Width="100%"/>
<Literal
Text="Location:" GridPanel.NoWrap="true"/>
<Edit ID="Location"
Width="100%" GridPanel.Width="100%"/>
<hr GridPanel.ColSpan="2"
/>
<Literal Text="URL:"
GridPanel.NoWrap="true"/>
<Edit ID="URL" Disabled="true"
Width="100%" GridPanel.Width="100%"/>
<hr GridPanel.ColSpan="2"
/>
<Literal Text="Checks:" GridPanel.NoWrap="true"
/>
<Checkbox ID="Check1" Header="Check one"
/>
<Literal Text="" GridPanel.NoWrap="true"
/>
<Checkbox ID="Check2" Header="Another check"
/>
</GridPanel>
</WizardFormIndent>
</WizardFormPage>
<WizardFormPage
ID="WizardPageThree" Header="Page 3" Text="More things to do here. When done,
click next to continue."
Icon="People/48x48/user1.png">
<WizardFormIndent>
<GridPanel
ID="FieldsOthers" Columns="2" Width="100%"
CellPadding="2">
<Literal Text="Something else:"
GridPanel.NoWrap="true"/>
<Edit ID="SomethingElse" Width="100%"
Change="OnNameChanged" GridPanel.Width="100%"/>
<Literal
Text="More text:" GridPanel.NoWrap="true"/>
<Edit ID="MoreText"
Width="100%"
GridPanel.Width="100%"/>
</GridPanel>
</WizardFormIndent>
</WizardFormPage>
<WizardFormLastPage
ID="LastPage"
Icon="People/48x48/user1.png">
<Border>
<Literal
Text="The wizard has
completed."/>
</Border>
</WizardFormLastPage>
</WizardForm>
</ExampleWizard>
</control>
Step 2: Wizard C# code
Now, for our wizard to even show and do, well, anything, we need to define it and handle some example events, like validating a Edit control and enable/disable buttons. The class is based on sitecores own
WizardForm in order to get all the already-existing (and
great) functionality.
here's the code:
namespace Interfolio.Examples
{
public class ExampleWizardForm :
WizardForm
{
// specify each control we need to access from the xml as
'protected' and it'll be available
protected Edit Name;
public
ExampleWizardForm()
{
}
protected override void OnLoad(EventArgs
e)
{
base.OnLoad(e);
if (!Context.ClientPage.IsEvent)
{
// handle
initial code here
}
}
protected void OnNameChanged()
{
// check
to make sure the name Edit is not empty (in a negative boolean style)
bool
IsOk = (this.Name.Value == null) (this.Name.Value.Length ==
0);
base.NextButton.Disabled = IsOk;
if
(IsOk)
{
Context.ClientPage.ClientResponse.Focus("Name");
}
Context.ClientPage.ClientResponse.SetReturnValue(true);
}
protected
override void ActivePageChanged(string page, string
oldPage)
{
base.ActivePageChanged(page, oldPage);
if (page ==
"WizardPageTwo")
{
// make sure next button is disabled unless the Name is
entered
this.OnNameChanged();
}
else if (page ==
"LastPage")
{
base.BackButton.Disabled = true;
}
}
protected
override bool ActivePageChanging(string page, ref string newpage)
{
if
(newpage == "LastPage")
{
// disable the back button since we've finished
the wizard
base.BackButton.Disabled = true;
// return the boolean status
of our 'commit' method
return this.WhatWeWantToDo();
}
return
base.ActivePageChanging(page, ref newpage);
}
private bool
WhatWeWantToDo()
{
// really do something else here, this is just an
example..
return true;
}
}
}
Step 3: Command C# code
The purpose of this command is to make your newly created wizard launchable from pretty much anywhere you want. It is based on sitecores own Command.
here's the code:
namespace Interfolio.Examples
{
[Serializable]
public class OpenWizard
: Command
{
public OpenWizard()
{
}
public override void
Execute(CommandContext context)
{
// get the uri of our wizard by finding
the control using Sitecore's UIUtil
string controlUrl =
Sitecore.UIUtil.GetUri("control:ExampleWizard");
// broadcast the need to
show the wizard to the sitecore shell
Context.ClientPage.ClientResponse.Broadcast(Context.ClientPage.ClientResponse.ShowModalDialog(controlUrl),
"Shell");
}
public override CommandState QueryState(CommandContext
context)
{
return base.QueryState(context);
}
protected void
Run(Sitecore.Web.UI.Sheer.ClientPipelineArgs args)
{
}
}
}
Step 4: Config Additions
Before using our code anywhere we need to tell Sitecore that it's available, which is normal since it's new code.
In the
Web.Config file, locate the section
<controlsources> and add the source folder of your new code:
<source mode="on" namespace="Interfolio.Examples"
folder="/sitecore modules/shell/interfolio/Examples" deep="true">
</source>
In the
Commands.config file (located at
\App_Config), add the following:
<command name="interfolio:examplewizard"
type="Interfolio.Examples.OpenWizard,Interfolio.Examples" />
Save both files.
As you may have noticed the example is located in interfolio\Examples, this is just where i stored it for this tutorial, you can have any folder you wish, just make sure that if you change the namespace or assembly or folders that you refactor the change onto the rest of your code.
Step 5: Launching the wizard
Now all the code is complete and we only need to have a way of launching it within sitecore. While this approach isn't really that durable unless your wizard is
extremely generic it's still an easy way to quickly try something you've done.
- Open Sitecore in your browser, login and switch database to 'core'
- Navigate to Sitecore/System/Context Menus/Default and duplicate the 'New' item and name it 'ExampleWizard'
- Change the fields DisplayName to 'ExampleWizard' and Message to 'interfolio:examplewizard(id=$Target)'
- Save it and switch back to the 'master' database
That's it!
If you've followed these steps correctly you should by now be able to right click an item in the Content Editor and click ExampleWizard which will launch your newly created wizard.
Take care,
P.