Way to intercept / cancel a tab change in RadzenTabs (unsaved-changes guard)?

Hi,

I'm looking for a way to prevent or defer a tab change in RadzenTabs based on the current tab's state, and I can't find a supported mechanism for it.

Use case

One of my tabs contains a input. When the user has made changes that are not yet saved (the input is "dirty") and then clicks another tab, I want to:

  1. Intercept the tab change before it happens,
  2. Show a confirmation dialog ("You have unsaved changes. Discard them and switch, or stay and save first?"), and
  3. Either allow the switch (user chose Discard) or cancel it and keep the user on the current tab (user chose Save / Cancel).

The problem

As far as I can tell, RadzenTabs only exposes events that fire after the tab has already switched:

  • Change / SelectedIndexChanged are raised once the new tab is already active.

There doesn't seem to be a cancelable "before change" hook — nothing like a Changing event with a Cancel flag, or an async callback whose result could veto the switch (e.g. Func<int, Task>).

Because of this, by the time I learn about the change, the user is already on the new tab, so I can't cleanly block the navigation.

My questions

  1. Is there a supported way to intercept/cancel a tab change before it takes effect that I've missed?
  2. If not, what is the recommended pattern for an "unsaved changes" guard with RadzenTabs today? Is forcing SelectedIndex back to the previous value in the Change handler (after an async confirmation dialog) the intended approach, or is there something cleaner?
  3. Are there any plans to add a cancelable "Changing"/"BeforeChange" event (ideally async, so it can await a dialog result)?

Environment: Radzen.Blazor 11, .NET 10, render mode Server.

Thanks a lot for any guidance!

Hi @kl1mm,

We've added a cancelable CanChange event to RadzenTabs (same pattern as RadzenSteps.CanChange). It is raised before the selected tab changes in response to user interaction (mouse click or keyboard) and the callback can be async, so you can await a confirmation dialog and veto the switch:

<RadzenTabs CanChange=@OnTabCanChange>
    <Tabs>
        <RadzenTabsItem Text="Orders">...</RadzenTabsItem>
        <RadzenTabsItem Text="Customers">...</RadzenTabsItem>
    </Tabs>
</RadzenTabs>

@code {
    bool hasUnsavedChanges;

    async Task OnTabCanChange(TabsCanChangeEventArgs args)
    {
        if (hasUnsavedChanges)
        {
            var discard = await DialogService.Confirm("You have unsaved changes. Discard them?", "Unsaved changes");

            if (discard != true)
            {
                args.PreventDefault();
            }
        }
    }
}

The event args expose SelectedIndex (the current tab) and NewIndex (the tab the user is switching to). Calling args.PreventDefault() cancels the change - the tab stays selected and Change/SelectedIndexChanged are not raised. Works in both Server and Client render mode.

It will be part of our next release scheduled for later this week.

Hi @enchev,

that's fantastic — thank you for the incredibly fast turnaround, and for adding a proper cancelable CanChange event rather than a workaround.

The async support is exactly what I needed so I can await the confirmation dialog before vetoing the switch, and having SelectedIndex/NewIndex on the args plus PreventDefault() makes the whole thing clean.

I'll pick it up as soon as the release lands later this week.

Thanks again for the quick and thorough response!