Question

I have an asp:wizard control that contains five WizardSteps. All of these steps have form controls, and most of these controls have validators. When the user steps through the wizard with the next and previous buttons everything is working great, and validation triggers as it should. However, if the user chooses to navigate the wizard using the links in the SideBar, he or she could skip some of the steps. When the last page is submitted (which is a summary page) there might be controls in the wizard that are invalid.

What I want to do is to check the state of all controls (or run all validators) when the user clicks the finish button, or when the user enters the summary page. I have made an attempt to run all the validators in the FinishButtonClick event by doing this:

bool validates = true;
foreach (IValidator validator in this.Validators) {
    validator.Validate();
    if (!validator.IsValid) {
        validates = false;
    }
}

e.Cancel = !validates;

But when I do this every validator claims that they are valid. I have also tried to set all controls to Visible = true; prior to this code block, but this has no effect. Any idea what could be wrong? Or is it a better way of doing this, maybe a native function to the wizard control that I'm missing?

Was it helpful?

Solution

You can't do this because the controls that you are trying to validate are not rendered on the page. i.e. the validators are not there, so Page.Validate() and Page.IsValid will return true because there are no validators, so everything is valid. Makes sense, I hope?

Go to View Source and you will see that the source only contains markup for the current step of the wizard. So any validators on previous pages are not rendered and hence not checked.

I would suggest hiding the SideBar. That way the user cannot skip pages and when they click 'Next' the current controls will be validated, so they can only continue if they have completed the page that they are on.

P.S. You don't need to loop through all validators and check they are valid. Just use Page.Validate() (you can even pass a ValidationGroup to this method) and then check the Page.IsValid boolean.

EDIT: As per comments below:

Page Property:

public bool PageOneValid
{
    get
    {
        if (ViewState["PageOneValid"] == null)
            return false;

        return (bool)ViewState["PageOneValid"];
    }
    set
    {
        ViewState["PageOneValid"] = value;
    }
}

On page one next click or sidebar click:

Page.Validate("PageOne");
PageOneValid = Page.IsValid;

OTHER TIPS

One option would be to validate page state in the SideBarButtonClick event, setting Cancel to true if it fails validation. Then your users should never reach the summary page with invalid data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top