Radzen DataGrid 多选与异步 OnInitialized

Radzen DataGrid Multiple Selection with async OnInitialized

我正在开发一个 Blazor 页面,我想在其中使用 Radzens DataGrid。 我使用 DataGrid Inline Editing 的例子来编辑和添加我的数据库的联系人。以及整体结构。
这完全没问题。

我从数据库中填充我的联系人列表:

protected override async Task OnInitializedAsync()
{
    base.OnInitialized();
    contacts = await Task.Run(()=>ContactService.GetAllContacts());
}

我也想补充DataGrid Multiple Selection。 这就是问题所在。当我在代码中实现它时,加载 Razor 组件时出现 ArgumentNullException。

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" />

当我切换到同步 OnInitialized 时,它可以正常工作。 但是有没有办法让它异步工作?

protected override void OnInitialized()
{
    base.OnInitialized();
    Users = UserService.GetAllUsers();
}

我的剃刀组件:

@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();
    }
}

请将您的 RadzenDataGrid 包装成以下条件:

if(contacts?.Count > 0)

在这种情况下,它不会渲染您的组件,直到获得必要的参数