How to add skip button to ASP.NET Wizard? - asp.net

I know how can I skip steps programmatically but I need "Skip" button too.

If you wish to add a new button to the wizard control then you will need to replace the existing Templates by creating custom
WizardStepNavigationTemplates(this is the template which is responsible for the controls which are displayed when on any normal wizard step)
WizardStartNavigationTemplate(this is the template which is responsible for the controls which are displayed when on the FIRST step of the wizard) and
WizardFinishNavigationTemplate (this is the template which is responsible for the controls which are displayed when on the Last step of the wizard)
internal class CustomWizardStartNavigationTemplate : CustomWizardNavigationTemplateBase
{
#region ITemplate Members
public CustomWizardStartNavigationTemplate(WizardDisplayConfig wizardDisplayConfig):base(wizardDisplayConfig){ }
/// <summary>
/// this overrides the method to define the navigation controls which will appear in the template.
/// Literal control is used to put spacing between the controls.
/// </summary>
public override void InstantiateIn(Control container)
{
Literal spacingliteral = new Literal();
spacingliteral.Text += "&nbsp;";
Button btnSkip = new Button();
Button btnSave= new Button();
Button btnNext= new Button();
container.Controls.Add(btnSave);
container.Controls.Add(spacingliteral);
container.Controls.Add(btnNext);
container.Controls.Add(spacingliteral);
container.Controls.Add(btnSkip);
}
#endregion
}
Something like below is a sample implementation of how you can achieve the desired results. Note that by creating these new templates you will need to add button click events etc which i have not shown in my example. This is so when user clicks the button they will be moved to the next step etc.Hope this helps.
cheers
Niall

Related

How to extend the context menu inside the rehosted workflow designer?

We are using a rehosted designer (currently WF 4.0) with a lot of custom activities, all of them have custom designers. For a bunch of them, I would like to add entries to the context menu of the designer when in design mode. I'm talking about this menu:
E.g. for a XAML coded activity I would like to have an "Open source..." entry which will load the XAML source of that specific activity into a new designer. To do that I must add the entry to the menu, and when clicked figure out on which activity it was clicked. Both parts are unclear to me. How can I achieve that?
In WF 3 there was the ActivityDesignerVerb class to do that. In WF 4 there seems to be workflowDesigner.Context.Services.Publish<ICommandService>(...), but I can't figure out how to use that to add a custom action to the context menu. How can I do that?
This SO entry shows something for internal debugger commands, but I want to add a completely new command.
Solving it in the host
If you want to solve this on the workflow designer host, and not in the individual activities, it's quite simple and straightforward to do this.
When you host the workflow designer and create the workflow designer, you can simply access its ContextMenu property and modify its Items collection.
var wfd = new WorkflowDesigner();
wfd.ContextMenu.Items.Add(new MenuItem() { Header = "Hello", Command = yourCommand, });
If you want different menu items for each activity, you can subscribe to the SelectionChanged event:
wfd.Context.Items.Subscribe<Selection>(SelectionChanged);
And then implement your own logic:
private void SelectionChanged(Selection selection)
{
// Remove old menu item
if (oldMenuItem != null)
{
wfd.ContextMenu.Items.Remove(oldMenuItem);
oldMenuItem = null;
}
var modelItem = selection.PrimarySelection;
if (selection.SelectionCount == 1 && modelItem != null)
{
// Get activity type
var activityType = modelItem.ItemType;
var menuItem = new MenuItem() { /* ... */ };
wfd.ContextMenu.Items.Add(menuItem);
oldMenuItem = menuItem;
}
}
Solving it in the activity designer
If you want to always show a specific context menu item regardless of where your workflow designer UI is hosted, you can create a custom item in your activity designer XAML:
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding YourCommand}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>
OK so all you need to do is implement the ICommand interface on your custom activity.
So, for example - expose a custom command property from the customer activity class, then in the constructor apply a delegate event to the command handler -
/// <summary>
/// Custom activity
/// </summary>
public partial class CustomActivityDesigner
{
/// <summary>
/// Command used to display a dialog at design time
/// </summary>
public ICommand ShowCustomDialog{ get; set; }
public CustomSchedulerDesigner()
{
InitializeComponent();
ShowCustomDialog= new DelegateCommand(x =>
//Do some stuff here that will display your dialog
//you may want to consider passing the `this.ModelItem`
//to your dialog so it can then interact with the ModelTrees etc
//for example
var dialog = new MyDialog(this.ModelItem);
dialog.ShowDialog();
);
}
}
Finally,
hook the new command up to the UI via the activity designer xaml.
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding ShowCustomDialog}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>

State of checkbox lost after postback in a custom template field

I have created a custom checkbox template field by deriving it from System.Web.UI.WebControls.TemplateField. The template for this field has been created by creating a class which implements ITemplate interface. When any postback happens on the page the values in the checkboxes is lost.
To get this working temporarily I have used viewstate to store the state of checkboxes in the checkbox column, but going further I want to completely avoid this as I will be using more template fields in same fashion in my application.
Please let me know if I am missing anything.
Following is the code:
namespace MyControls
{
public class CheckBoxTemplateField : TemplateField
{
public CheckBoxTemplateField()
{
this.HeaderTemplate = new CheckBoxTemplate();
this.ItemTemplate = new CheckBoxTemplate();
}
}
public class CheckBoxTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
CheckBox chk = new CheckBox();
container.Controls.Add(chk);
}
}
}
Regards,
Gaurav
checkbox is known with their problem maintaining their value in postback
1 solution is to store its value in hidden fiesld and to read it in server.
p.s. thhis has nothing to do with viewstate.input control doesnt saves their value in viewstate ( excpet textbox which has the 'ontextchange' event)

ITemplate, the reason for leaving InstantiateIn(Control container)

I'm implementing the ITemplate interface in ListView control. If i realize it for ItemTemplate in my custom class, everything will be OK. I mean, the runtime will invoke InstantiateIn when i use
ListView.ItemTemplate = new CustomClass();
CustomClass :ITemplate
{
public void InstantiateIn(Control container)
{
HtmlTable table = CreateHeader();
container.Controls.Add(table);
}
...
}
But i want to do the same with ListView.LayoutTemplate. In this case, the runtime invokes InstantiateIn only one time, but every next update it leaves my method. What is the reason for it?
Layout template says how the root container does look like, it is not per item thing.
I have to change my LayoutTemplate after clicking different buttons.
And My LayoutTemplate has a header for the whole ListView. I have to change it, it depends on button.
Also i have two custom classes with implementations of ITemplate (one for ItemTemplate and one for LayoutTemplate). I am going to realise the folowing behaviour:
1). If i click Button1
ListView.ItemTemplate = new CustomItemClass1();
ListView.LayoutTemplate = new CustomLayuotClass1();
2). If i click Button2
ListView.ItemTemplate = new CustomItemClass2();
ListView.LayoutTemplate = new CustomLayuotClass2();
But i can't see my header of LayoutTemplate more, then one time.

Dynamically added PostBackTrigger in Custom Server Control not beeing rendered correctly

I'm building a custom server control derived from CompositeControl.
The control contains a number of child controls (Labels, DropDownList, ListSearchExtender, etc). All of them reside inside an UpdatePanel.
The control also publishes events. For this I added two Properties: EnableCallBacks and CallBacksAsPostBacks. Those two properties should configure the postback behaviour of the update panel.
Any ideas what a correct implementation should look like?
I'm getting some problems with the way I implemented it:
the PostBackTrigger does not always get rendered into the output html.
Having both Triggers.Add(trigger) and Controls.Add(_updatePanel) inside the CreateChildControls methods leads to the PostBackTrigger always being rendered, even if I remove it later on (e.g. within RenderControl() or PreRender()). If I do not add the trigger here but later on, then it does never get rendered. At this stage I do not have the correct values of all my properties yet (e.g. EnableCallBacks and CallBacksAsPostBacks).
It is not possible to place the statement of Controls.Add(_updatePanel) inside the RenderControl-method due to it beeing too late for AJAX (latest ist PreRender() otherwise I get an exception).
Ideally I would instantiate all controls in CreateChildControls() and then set their values later on in e.g. PreRender or RenderControl
Having both statements in the PreRender method results in, that the trigger gets rendered corretly depending on my settings in the containing page, but I don't get the DropDownList populated with its data from the ViewState (on call/postbacks).
protected override void CreateChildControls()
{
base.CreateChildControls();
_updatePanel = new UpdatePanel();
_updatePanel.ID = "FprDropDownList_UpPnl";
_updatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
_label = new FprLabel();
_label.ID = "FprDropDownList_Lbl";
_updatePanel.ContentTemplateContainer.Controls.Add(_label);
_dropDownList = new DropDownList();
_dropDownList.ID = "FprDropDownList_Ddl";
_dropDownList.CssClass = "fprDropDownList";
_dropDownList.AutoPostBack = true;
_updatePanel.ContentTemplateContainer.Controls.Add(_dropDownList);
_label.AssociatedControlID = _dropDownList.ClientID;
_listSearchExtender = new ListSearchExtender();
_listSearchExtender.ID = "FprDropDownList_Lse";
_listSearchExtender.TargetControlID = _dropDownList.ClientID;
_listSearchExtender.PromptPosition = ListSearchPromtPosition;
_listSearchExtender.PromptCssClass = "fprListSearchExtender";
_updatePanel.ContentTemplateContainer.Controls.Add(_listSearchExtender);
_ddlPostBackTrigger = new PostBackTrigger();
_ddlPostBackTrigger.ControlID = _dropDownList.ClientID;
//_updatePanel.Triggers.Add(_ddlPostBackTrigger);
Controls.Add(_updatePanel);
}
protected override void OnPreRender(EventArgs pE)
{
if (EnableCallBacks)
{
_dropDownList.SelectedIndexChanged += DropDownList_SelectedIndexChanged;
}
if (EnableCallBacks && CallBacksAsPostBacks)
{
_updatePanel.Triggers.Add(_ddlPostBackTrigger);
}
//Controls.Add(_updatePanel);
base.OnPreRender(pE);
}
public override void RenderControl(HtmlTextWriter pWriter)
{
// Do some things... like set Enable-state of child controls
base.RenderControl(pWriter);
}
You should add your dynamic controls in PreInit for the events to fire properly.
Use this event for the following:
Check the IsPostBack property to
determine whether this is the first
time the page is being processed. The
IsCallback and IsCrossPagePostBack
properties have also been set at this
time.
Create or re-create dynamic
controls.
Set a master page
dynamically.
Set the Theme
property dynamically.
Read or set
profile property values.

How to put an event in dynamic creation on flex?

Please help. I want to add a click event on checkbox that i created dynamically so that i know what checkbox I click.
Heres my code on action script:
var myCheckbox:CheckBox = new CheckBox();
vbox.addChild(myCheckbox);
How to add click event on checkbox?
private function myCheckboxClicked(event:MouseEvent)
{
// doStuff();
}
...
myCheckbox.addEventListener(MouseEvent.CLICK, myCheckboxClicked);
As long as it inherits EventDispatcher, you can attach a listener and it'll send events as normal.

Resources