I am working an a Blazor page where I want to make use of Radzens DataGrid.
I used the example of the DataGrid Inline Editing for editing and adding contacts of my database. And the structure overall.
This works totally fine.
I populate my list of contacts from the database within:
protected override async Task OnInitializedAsync()
{
base.OnInitialized();
contacts = await Task.Run(()=>ContactService.GetAllContacts());
}
I also want to add the DataGrid Multiple Selection. And there lies the problem. When I implement it in my code I get a ArgumentNullException, when loading the Razor Component.
ArgumentNullException: Value cannot be null. (Parameter 'source') System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
Contact_Management_Tool.Pages.Pages__Host.ExecuteAsync() in _Host.cshtml
Layout = "_Layout";
}
<link rel="stylesheet" href="_content/Radzen.Blazor/css/default-base.css">
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
<component type="typeof(App)" render-mode="ServerPrerendered" />
When I switch to an synchronous OnInitialized, it works like it should. But is there a way to make it work asynchronously?
protected override void OnInitialized()
{
base.OnInitialized();
Users = UserService.GetAllUsers();
}
My Razor Component:
@page "/Contacts"
@using Radzen
@using Event_Management_Tool.Data
@using Event_Management_Tool.Data.Control
@using Event_Management_Tool.Data.Model
@using Microsoft.EntityFrameworkCore
@inject ContactService ContactService
@inject UserService UserService
@inject AuthenticateUser authenticateUser
@inject IJSRuntime JsRuntime
<h3>ContactsPage</h3>
<RadzenDataGrid
@ref="contactsGrid" Data="@contacts" AllowColumnResize="true" EditMode="DataGridEditMode.Single"
RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow" AllowPaging="true" PageSize="20"
AllowSorting="true" AllowFiltering="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
TItem="ContactModel" AllowRowSelectOnRowClick="true" SelectionMode="DataGridSelectionMode.Multiple" @bind-Value=@selectedContacts>
<Columns>
<RadzenDataGridColumn TItem="ContactModel" Width="40px" Sortable="false" Filterable="false">
<HeaderTemplate>
<RadzenCheckBox TriState="false" TValue="bool" Value="@(contacts.Any(i => selectedContacts != null && selectedContacts.Contains(i)))" Change="@(args => selectedContacts = args ? contacts.ToList() : null)" />
</HeaderTemplate>
<Template Context="contacts">
<RadzenCheckBox TriState="false" Value="@(selectedContacts != null && selectedContacts.Contains(contacts))" TValue="bool" Change=@(args => { contactsGrid.SelectRow(contacts); }) />
</Template>
</RadzenDataGridColumn>
<!-- ID -->
<RadzenDataGridColumn TItem="ContactModel" Property="Id" Title="ID" Width="50px" />
<!-- Salutation -->
<RadzenDataGridColumn TItem="ContactModel" Property="Salutation" Title="Salutation">
<EditTemplate Context="contact">
<RadzenTextBox @bind-Value="contact.Salutation" Style="width:100%; display: block" Name="Salutation" />
<RadzenRequiredValidator Text="Salutation is required" Component="Salutation" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<!-- Suffix -->
<RadzenDataGridColumn TItem="ContactModel" Property="Suffix" Title="Suffix">
<EditTemplate Context="contact">
<RadzenTextBox @bind-Value="contact.Suffix" Style="width:100%; display: block" Name="Suffix" />
</EditTemplate>
</RadzenDataGridColumn>
<!-- FirstName -->
<RadzenDataGridColumn TItem="ContactModel" Property="FirstName" Title="FirstName">
<EditTemplate Context="contact">
<RadzenTextBox @bind-Value="contact.FirstName" Style="width:100%; display: block" Name="FirstName" />
<RadzenRequiredValidator Text="FirstName is required" Component="FirstName" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<!-- LastName -->
<RadzenDataGridColumn TItem="ContactModel" Property="LastName" Title="LastName">
<EditTemplate Context="contact">
<RadzenTextBox @bind-Value="contact.LastName" Style="width:100%; display: block" Name="LastName" />
<RadzenRequiredValidator Text="LastName is required" Component="LastName" Popup="true" />
</EditTemplate>
</RadzenDataGridColumn>
<!-- Owner -->
<RadzenDataGridColumn TItem="ContactModel" Property="User.Name" Title="Owner"/>
<!-- Buttons -->
<RadzenDataGridColumn TItem="ContactModel" Context="ContactModel" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="120px">
<Template Context="contact">
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@(args => EditRow(contact))" @onclick:stopPropagation="true">
</RadzenButton>
</Template>
<EditTemplate Context="contact">
<RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRow(contact))">
</RadzenButton>
<RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEdit(contact))">
</RadzenButton>
</EditTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="ContactModel" Context="contact" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="60px">
<Template Context="contact">
<RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(contact))" @onclick:stopPropagation="true">
</RadzenButton>
</Template>
<EditTemplate Context="contact">
<RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(contact))">
</RadzenButton>
</EditTemplate>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
<RadzenButton Icon="add_circle_outline" style="margin-top: 10px" Text="Add New Contact" Click="@InsertRow" Disabled=@(contactToInsert != null)/>
@code {
RadzenDataGrid<ContactModel> contactsGrid;
UserModel CurrentUser;
IList<ContactModel> selectedContacts;
IEnumerable<ContactModel> contacts;
IEnumerable<UserModel> Users;
//This doesnt work
protected override async Task OnInitializedAsync()
{
base.OnInitialized();
CurrentUser = authenticateUser.GetUser();
contacts = await Task.Run(()=>ContactService.GetAllContacts());
Users = await Task.Run(()=>UserService.GetAllUsers());
}
//This works
//protected override void OnInitialized()
//{
// base.OnInitialized();
// CurrentUser = authenticateUser.GetUser();
// contacts = ContactService.GetAllContacts();
// Users = UserService.GetAllUsers();
//}
//EDIT
async Task EditRow(ContactModel contact)
{
await contactsGrid.EditRow(contact);
}
async void OnUpdateRow(ContactModel contact)
{
if (contact == contactToInsert)
{
contactToInsert = null;
}
ContactService.UpdateContact(contact);
await OnInitializedAsync();
StateHasChanged();
}
//SAVE
async Task SaveRow(ContactModel contact)
{
if (contact == contactToInsert)
{
contactToInsert = null;
}
await contactsGrid.UpdateRow(contact);
}
//CANCEL EDIT
void CancelEdit(ContactModel contact)
{
if (contact == contactToInsert)
{
contactToInsert = null;
}
contactsGrid.CancelEditRow(contact);
var contactEntry = ContactService.EntryContact(contact);
if (contactEntry.State == EntityState.Modified)
{
contactEntry.CurrentValues.SetValues(contactEntry.OriginalValues);
contactEntry.State = EntityState.Unchanged;
}
}
//DELETE
async Task DeleteRow(ContactModel contact)
{
if (contact == contactToInsert)
{
contactToInsert = null;
}
if (contacts.Contains(contact))
{
bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Wollen Sie den Adressat löschen?");
if (confirmed)
{
ContactService.DeleteContact(contact);
await OnInitializedAsync();
StateHasChanged();
await contactsGrid.Reload();
}
}
else
{
contactsGrid.CancelEditRow(contact);
}
}
//CREATE NEW ROW
ContactModel contactToInsert;
async Task InsertRow()
{
contactToInsert = new ContactModel();
await contactsGrid.InsertRow(contactToInsert);
}
//CREATE NEW USER
async void OnCreateRow(ContactModel contact)
{
contact.UserId = CurrentUser.Id;
ContactService.CreateContact(contact);
await OnInitializedAsync();
StateHasChanged();
}
}
CodePudding user response:
Please wrap your RadzenDataGrid
with this condition:
if(contacts?.Count > 0)
In this case it will not render your component until getting the necessary parameter for it