DataGrid Inline Edit with low record count issue

I'm having some funny behavior on Inline Edit for data grid. This seemed to be working a few weeks ago, but stopped when I updated Radzen components. I don't know if this is a new bug or if I'm missing something, however, when I add a new item for inline, if there aren't enough records to have multiple pages, it appears as if it's overwriting a current object. Example:

If I have just one object:


and I click to Add a new type, I get:

If I update and save, it will show both:

But if I add another it appears to behave the same way:

And saving still adds it:

If I go over the page size, it appears fine because it just "looks" like it's shifting one to the next page. But this behavior will be extremely confusing in several instances I'm using DataGrid for because they will always have just a few items in the grid.

Here's the code for the grid:

<RadzenDataGrid @ref="opportunityLossTypeGrid" TItem="OpportunityLossType" Count="@count" Data="@opportunityLossTypes" EditMode="DataGridEditMode.Single"
                RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow" Sort="@Reset" Page="@Reset" Filter="@Reset" AllowAlternatingRows="false" AllowPaging="true"
                AllowSorting="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" AllowFiltering="true" PageSize="10" Density="Density.Compact" AllowVirtualization="true">
    <Columns>
        <RadzenDataGridColumn TItem="OpportunityLossType" Title="Actions" Context="lossType" Filterable="false" Sortable="false" Width="150px">
            <Template Context="lossType">
                <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.ExtraSmall" Click="@(args => EditRow(lossType))" @onclick:stopPropagation="true">
                </RadzenButton>
                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.ExtraSmall" class="my-1 ms-1" Click="@(args => DeleteRow(lossType))" @onclick:stopPropagation="true">
                </RadzenButton>
            </Template>
            <EditTemplate Context="lossType">
                <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.ExtraSmall" Click="@((args) => SaveRow(lossType))">
                </RadzenButton>
                <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.ExtraSmall" class="my-1 ms-1" Click="@((args) => CancelEdit(lossType))">
                </RadzenButton>
                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Variant="Variant.Flat" Shade="Shade.Lighter" Size="ButtonSize.ExtraSmall" class="my-1 ms-1" Click="@(args => DeleteRow(lossType))">
                </RadzenButton>
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn TItem="OpportunityLossType" Title="Loss Type" Property="Reason">
            <EditTemplate Context="lossType">
                <RadzenTextBox @bind-Value="lossType.Reason" Name="Reason"></RadzenTextBox>
                <RadzenRequiredValidator Text="Reason is required" Component="Reason" Popup=true />
            </EditTemplate>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>
<RadzenButton ButtonStyle="ButtonStyle.Success" Icon="add_circle_outline" class="mt-2 mb-4" Text="Add New Loss Type" Click="@InsertRow" Disabled=@(opportunityLossTypeToInsert != null || opportunityLossTypeToUpdate != null) />

@code {
    RadzenDataGrid<OpportunityLossType>? opportunityLossTypeGrid;
    IEnumerable<Status> statuses = Enum.GetValues(typeof(Status)).Cast<Status>();

    IEnumerable<OpportunityLossType>? opportunityLossTypes;

    int count;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        opportunityLossTypes = await OpportunityLossTypeService.GetOpportunityLossTypesAsync();
        count = opportunityLossTypes.Count();
    }

    void Reset()
    {
        opportunityLossTypeToInsert = null;
        opportunityLossTypeToUpdate = null;
    }

    async Task EditRow(OpportunityLossType type)
    {
        opportunityLossTypeToUpdate = type;
        if (opportunityLossTypeGrid != null)
        {
            await opportunityLossTypeGrid.EditRow(type);
        }
    }

    protected void OnUpdateRow(OpportunityLossType type)
    {
        if (type == opportunityLossTypeToInsert)
        {
            opportunityLossTypeToInsert = null;
        }
        opportunityLossTypeToUpdate = null;

        OpportunityLossTypeService.UpdateOpportunityLossTypeAsync(type);
    }

    async Task SaveRow(OpportunityLossType type)
    {
        await opportunityLossTypeGrid.UpdateRow(type);
    }

    void CancelEdit(OpportunityLossType type)
    {
        if (type == opportunityLossTypeToInsert)
        {
            opportunityLossTypeToInsert = null;
        }
        opportunityLossTypeToUpdate = null;
        opportunityLossTypeGrid.CancelEditRow(type);

    }

    async Task DeleteRow(OpportunityLossType type)
    {
        if (type == opportunityLossTypeToInsert)
        {
            opportunityLossTypeToInsert = null;
        }

        if (type == opportunityLossTypeToUpdate)
        {
            opportunityLossTypeToUpdate = null;
        }

        if (opportunityLossTypes.Contains(type))
        {
            await OpportunityLossTypeService.DeleteOpportunityLossTypeAsync(type);
            opportunityLossTypes = await OpportunityLossTypeService.GetOpportunityLossTypesAsync();
            count = opportunityLossTypes.Count();
        }
        else
        {
            opportunityLossTypeGrid.CancelEditRow(type);
            await opportunityLossTypeGrid.Reload();
        }
    }

    OpportunityLossType? opportunityLossTypeToInsert;
    OpportunityLossType? opportunityLossTypeToUpdate;

    async Task InsertRow()
    {
        opportunityLossTypeToInsert = new();
        count++;
        if (opportunityLossTypeGrid != null)
        {
            await opportunityLossTypeGrid.InsertRow(opportunityLossTypeToInsert);
        }
    }

    async Task OnCreateRow(OpportunityLossType type)
    {
        OpportunityLossTypeService.AddOpportunityLossTypeAsync(type);

        opportunityLossTypeToInsert = null;

        opportunityLossTypes = await OpportunityLossTypeService.GetOpportunityLossTypesAsync(); 
        count = opportunityLossTypes.Count();
    }
}

Hi @gpankretz,

Can you reproduce this by modifying our demo?

I see that you have both paging and virtualization turned on - not sure why however these features are mutually exclusive.

Ah, the mutually exclusivity makes sense... and that was the problem. I wanted paged not virtualized. So, disabling the virtualization fixed the issue. Thank you.