--- sidebar_position: 5 title: Creation of a confirmation popup --- ## Creation of a confirmation popup In order to create our popup, create the `Modals` folder at the root of the site. Create the razor component `DeleteConfirmation.razor` and its class `DeleteConfirmation.razor.cs`. ```cshtml title="Modals/DeleteConfirmation.razor"

Are you sure you want to delete @item.DisplayName ?

``` ```csharp title="Modals/DeleteConfirmation.razor.cs" public partial class DeleteConfirmation { [CascadingParameter] public BlazoredModalInstance ModalInstance { get; set; } [Inject] public IDataService DataService { get; set; } [Parameter] public int Id { get; set; } private Item item = new Item(); protected override async Task OnInitializedAsync() { // Get the item item = await DataService.GetById(Id); } void ConfirmDelete() { ModalInstance.CloseAsync(ModalResult.Ok(true)); } void Cancel() { ModalInstance.CancelAsync(); } } ``` Open the `Pages/List.razor.cs` file and add the changes: ```csharp title="Pages/List.razor.cs" ... [Inject] public NavigationManager NavigationManager { get; set; } [CascadingParameter] public IModalService Modal { get; set; } ... private async void OnDelete(int id) { var parameters = new ModalParameters(); parameters.Add(nameof(Item.Id), id); var modal = Modal.Show("Delete Confirmation", parameters); var result = await modal.Result; if (result.Cancelled) { return; } await DataService.Delete(id); // Reload the page NavigationManager.NavigateTo("list", true); } ``` ## Concept: Cascading Parameters ### Component `CascadingValue` An ancestor component provides cascading value using the `CascadingValue` framework Blazor component, which encapsulates a subtree of a component hierarchy and provides a unique value to all components in its subtree. The following example shows the flow of theme information through the component hierarchy of a layout component to provide a CSS style class to child component buttons. The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses` and specifies theme information. :::info For the samples in this section, the application namespace is BlazorSample . When experimenting with the code in your own sample application, replace the application namespace with the namespace of your sample application. ::: ```csharp title="UIThemeClasses/ThemeInfo.cs" namespace BlazorSample.UIThemeClasses { public class ThemeInfo { public string? ButtonClass { get; set; } } } ``` The following layout specifies theme information ( `ThemeInfo` ) as a cascading value for all components that make up the layout body of the `Body` property. The value `ButtonClass` is assigned to `btn-success`, which is a style of start button. Any component descending in the component hierarchy can use the `ButtonClass` property through the cascading `ThemeInfo` value. ```cshtml title="Shared/MainLayout.razor" @inherits LayoutComponentBase @using BlazorSample.UIThemeClasses
@Body
@code { private ThemeInfo theme = new() { ButtonClass = "btn-success" }; } ``` ### Attribute `[CascadingParameter]` To use cascading values, descendant components declare cascading parameters using the `[CascadingParameter]` attribute. Cascading values are related to cascading parameters by type. The following component binds the cascading `ThemeInfo` value to a cascading parameter, optionally using the same `ThemeInfo` name. The parameter is used to define the CSS class for the `Increment Counter (Themed)` button. ```cshtml title="Pages/ThemedCounter.razor" @page "/themed-counter" @using BlazorSample.UIThemeClasses

Themed Counter

Current count: @currentCount

@code { private int currentCount = 0; [CascadingParameter] protected ThemeInfo? ThemeInfo { get; set; } private void IncrementCount() { currentCount++; } } ``` ### Cascading Multiple Values To cascade multiple values of the same type in the same subtree, supply a unique `Name` string to each `CascadingValue` component and its corresponding `[CascadingParameter]` attributes. In the following example, two `CascadingValue` components cascade different instances of `CascadingType`: ```cshtml ... @code { private CascadingType parentCascadeParameter1; [Parameter] public CascadingType ParentCascadeParameter2 { get; set; } ... } ``` In a descendant component, cascading parameters receive their cascading values from the ancestor component with the `Name` attribute: ```cshtml ... @code { [CascadingParameter(Name = "CascadeParam1")] protected CascadingType ChildCascadeParameter1 { get; set; } [CascadingParameter(Name = "CascadeParam2")] protected CascadingType ChildCascadeParameter2 { get; set; } } ``` ### Pass data in a component hierarchy Cascading parameters also allow components to pass data through a component hierarchy. Consider the following UI tab set example, where a tab set component manages a series of individual tabs. Create an `ITab` interface that tabs implement in a folder named `UIInterfaces`. ```csharp title="UIInterfaces/ITab.cs" using Microsoft.AspNetCore.Components; namespace BlazorSample.UIInterfaces { public interface ITab { RenderFragment ChildContent { get; } } } ``` The following `TabSet` component manages a set of tabs. The components of the `Tab` tab set, which are created later in this section, provide the list items ( `
  • ...
  • ` ) of the list ( `` ). `Tab` child components are not explicitly passed as parameters to `TabSet`. Instead, `Tab` child components are part of `TabSet` child content. However, the `TabSet` still requires a `Tab` reference to each component in order to display the headers and the active tab. To enable this coordination without requiring additional code, the `TabSet` component can present itself as a cascading value which is then retrieved by descendant `Tab` components. ```cshtml title="Shared/TabSet.razor" @using BlazorSample.UIInterfaces @code { [Parameter] public RenderFragment ChildContent { get; set; } public ITab ActiveTab { get; private set; } public void AddTab(ITab tab) { if (ActiveTab == null) { SetActiveTab(tab); } } public void SetActiveTab(ITab tab) { if (ActiveTab != tab) { ActiveTab = tab; StateHasChanged(); } } } ``` Descendant `Tab` components capture the `TabSet` container as a cascading parameter. The `Tab` components add to the `TabSet` coordinate and to set the active tab. ```cshtml title="Shared/Tab.razor" @using BlazorSample.UIInterfaces @implements ITab
  • @Title
  • @code { [CascadingParameter] public TabSet ContainerTabSet { get; set; } [Parameter] public string Title { get; set; } [Parameter] public RenderFragment ChildContent { get; set; } private string TitleCssClass => ContainerTabSet.ActiveTab == this ? "active" : null; protected override void OnInitialized() { ContainerTabSet.AddTab(this); } private void ActivateTab() { ContainerTabSet.SetActiveTab(this); } } ``` The following `ExampleTabSet` component uses the `TabSet` component, which contains three `Tab` components. ```cshtml title="Pages/ExampleTabSet.razor" @page "/example-tab-set"

    Greetings from the first tab!

    Hello from the second tab!

    @if (showThirdTab) {

    Welcome to the disappearing third tab!

    Toggle this tab from the first tab.

    }
    @code { private bool showThirdTab; } ```