Custom component in data grid column template is not updated when sorting data grid

During may way of getting used to the concepts and tool, I need some additional help, thanks in advance.

Inside a data grid, showing attachments, I am using a custom component in one of the columns, that only contains a data list, of tag names. The tag names are related to the AttachmentId of the data grid row.
My problem: if I reorder the data grid by clicking on the reorder icon in the column header of another column, the column showing the tags does not adapt its order -> wrong tags will be shown in the wrong row.

This is my component page "Tag List":


This is the template of the last column of my data grid, that does not react to reordering the data grid:

First approach: as you can see I tried to explicitly bind the AttachmentId value to my component (using a @bind-Value attribute), so it gets updated. Actually that's what I though this would do, according to this post. But that was just a first guess, and it looks as this is not my scenario.

In the documentation about custom components, I saw that the passed parameter is assigned to a property and according to this post I thought this causes the binding to row value, so my:
Second approach was to store the passed parameter (AttachmentId) in a property inside the custom component, to provoke a callback to the load event.

Or can I call the load() method from the data grid's RowRendering event? But how to get a custom component reference out of my the args parameter?

You can do the following in the custom component/page partial class:

in the example I've posted in your other thread:

1 Like

I applied your code like this and it works. When I reorder the data grid, the column containing the custom component updates correctly. Thank you!

using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using Radzen;
using Radzen.Blazor;

namespace MyApp.Pages
{
    public partial class TagListComponent
    {
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (!firstRender)
            {
                await Load();
            }            
            await base.OnAfterRenderAsync(firstRender);
        }
    }
}

Sorry, @enchev , just found out that this creates a DB query loop: the queries for reloading the tags is executed over and over:


I will analyse the scenario and post again, if I found the solution.

I don't see such behavior in my example. Database will be requested only when needed, on sort for example.

1 Like

After debugging I found out, that Load() does a TagList property update and the property update causes a Reload(), which I guess implicitly calls Load() again.

I checked the content (and each fields) of _TagList and value, and they look the same (both debug views look like this):
image.
Do I need to override the Equals method? or does it try to guess the primary key from the DB view and fails? (because the view does not have a primary key)
Sorry, if there is an obvious mistake, but currently I just can't spot it. Thanks for your advice.

Here is how to avoid this using Condition for the collection property in the custom component:

1 Like

Thank you, this condition was one part of the solution of my problem: means, before setting the property again and causing a reload I wanted to check all tags in my tag list component. But the equality check between the reloaded tag list for a row and the currently set tag list in this row, still returned false every time. What caused again a loop of SQL queries. Solution: I overrode the object method object.Equals() by creating a file AttachmentTagView.Custom.cs with this content:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyApp.Models.MyAppDb
{
  public partial class AttachmentTagView : IEquatable<Object>
  {
    // The regular Equals method, was always false. I needed to determine equality by the content of the tag relation entry.
    public override bool Equals(Object other)
    {
        if (other is null)
            return false;
        return this.TagId == ((AttachmentTagView)other).TagId && this.TagName == ((AttachmentTagView)other).TagName  &&
          this.ProjectId == ((AttachmentTagView)other).ProjectId && this.AttachmentId == ((AttachmentTagView)other).AttachmentId;
    }

    public override int GetHashCode() => (TagId, TagName, ProjectId, AttachmentId).GetHashCode();

  }
}

The function SequenceEqual() seems to use that function.
Just thought, I post this here fyi. Thanks for pointing me to the right direction.