Search code examples
c#htmlrazorblazor

Blazor selected Row parameter transfer


I have created a table here and would like to transfer the selected parameter to the component in the header area.

enter image description here

UserList.razor

<RadzenDataGrid Data="@usermodel"
                TItem="Userlistmodel"
                @bind-Value="@selectedUser"
                RowSelect=@RowSelect>
<Columns>
 <RadzenDataGridColumn TItem="Userlistmodel" Property="PNRUID" Title="PNRUID" Width="120px" />
 <RadzenDataGridColumn TItem="Userlistmodel" Property="PNR" Title="PNR" Width="120px" />
 <RadzenDataGridColumn TItem="Userlistmodel" Property="Nachname" Title="Nachname" Width="170px" />
 <RadzenDataGridColumn TItem="Userlistmodel" Property="Vorname" Title="Vorname" Width="170px" />
 <RadzenDataGridColumn TItem="Userlistmodel" Property="Geburtsdatum" Title="Geburtsdatum" /></Columns>
</RadzenDataGrid>

 <RadzenCard Style="margin-bottom:20px">
     User:
     <b>@selectedUser.FirstOrDefault()?.Nachname</b>
 </RadzenCard>

@code{

public IList<Userlistmodel>? selectedUser { get; set; }

void RowSelect( Userlistmodel userlistmodel )
{
    Console.WriteLine( userlistmodel.Nachname );
}
}

I tried the following to transfer the data (Nachname) in the header area. Something is still missing. A component (UserInfo.razor) is implemented in the header area.

UserInfo.razor

@using LMERP.AppAdmin.Shared.Models.UserMgmt

<div class="col d-flex justify-content-end">
    <h3>Header area</h3>
    <div class="col-1">
        <RadzenIcon Icon="account_box" Class="icon-s icon-outline icon-header-1 hidden-1 mt-header" />
    </div>
    <div class="col-1 pl-2">
        <div class="text div-header-1 hidden-2">
            <b>User:</b>
            @if ( selectedUser?.Any() == true )
            {
                foreach ( var role in selectedUser )
                {
                    <p class="mb-0">@role.Nachname</p>
                }
            }
            else
            {
                <p class="mb-0">Select Name</p>
            }
            </div>
    </div>
</div>

@code {
    [Parameter]
    public string Nachname { get; set; }

    [Parameter]
    public IList<Userlistmodel>? selectedUser { get; set; }

}

It also didn't work with CascadingValue.


Solution

  • You can do this by implementing an in-memory state container service like described here.

    Create a StateContainer class.

    public class StateContainer
    {
        private Userlistmodel? _selectedUser;
    
        public Userlistmodel? SelectedUser
        {
            get => _selectedUser;
            set
            {
                _selectedUser = value;
                NotifyStateChanged();
            }
        }
    
        public event Action? OnChange;
    
        private void NotifyStateChanged() => OnChange?.Invoke();
    }
    

    Register as singleton service in Program.cs (or scoped for Blazor server-side)

    builder.Services.AddSingleton<StateContainer>();
    

    Inside UserList.razor:

    @inject StateContainer State
    
    <RadzenDataGrid Data="@usermodel"
                    TItem="Userlistmodel"
                    @bind-Value="@selectedUser"
                    RowSelect=@RowSelect>
    <Columns>
     <RadzenDataGridColumn TItem="Userlistmodel" Property="PNRUID" Title="PNRUID" Width="120px" />
     <RadzenDataGridColumn TItem="Userlistmodel" Property="PNR" Title="PNR" Width="120px" />
     <RadzenDataGridColumn TItem="Userlistmodel" Property="Nachname" Title="Nachname" Width="170px" />
     <RadzenDataGridColumn TItem="Userlistmodel" Property="Vorname" Title="Vorname" Width="170px" />
     <RadzenDataGridColumn TItem="Userlistmodel" Property="Geburtsdatum" Title="Geburtsdatum" /></Columns>
    </RadzenDataGrid>
    
     <RadzenCard Style="margin-bottom:20px">
         User:
         <b>@selectedUser.FirstOrDefault()?.Nachname</b>
     </RadzenCard>
    
    @code{
    
        public IList<Userlistmodel>? selectedUser { get; set; }
    
        void RowSelect( Userlistmodel userlistmodel )
        {
            Console.WriteLine( userlistmodel.Nachname );
            State.SelectedUser = userlistmodel;
        }
    }
    

    and inside UserInfo.razor

    @implements IDisposable
    @inject StateContainer State
    
    @if (State.SelectedUser != null)
    {
        <p>@State.SelectedUser.Nachname</p>
    }
    
    @code {
        protected override void OnInitialized()
        {
            StateContainer.OnChange += StateHasChanged;
        }
    
        public void Dispose()
        {
            StateContainer.OnChange -= StateHasChanged;
        }
    }