GridForeignColumn from code not working

I am building a generic DataGrid Component that I want to generate via C#-code.

I have made it to work with razor-code (by hardcoding columns) but I am unable to do it in pure C# by generating GridColumns. To make it work with razor-code I created a CustomAdaptor component like this:

<GridColumns>
        <GridForeignColumn TValue="AvailabilityStatusModel" Field="StatusId" HeaderText="ewqewq" ForeignKeyValue="Description" ForeignKeyField="Id">
            <SfDataManager Adaptor="Syncfusion.Blazor.Adaptors.CustomAdaptor">
                <EntityManagerDataAdaptor TEntity="AvailabilityStatusModel" TId="short"></EntityManagerDataAdaptor>
            </SfDataManager>
        </GridForeignColumn>
    </GridColumns>

The thing I am struggling with is the GridForeignColumn in C#-code.

I have tried the following:

  • Set the child content of the column to this:
    • public RenderFragment CreateDataAdaptorRenderFragment(Type foreignType, Type foreignIdType) => builder =>
      {
      var dataAdaptorType = typeof(EntityManagerDataAdaptor).MakeGenericType(foreignType, foreignIdType);
      var sfDataManagerType = typeof(SfDataManager);

      builder.OpenComponent(0, sfDataManagerType);
      builder.AddAttribute(1, "Adaptor", Syncfusion.Blazor.Adaptors.CustomAdaptor);

      builder.AddAttribute(2, "ChildContent", (RenderFragment)((builder2) =>
      {
      builder2.OpenComponent(3, dataAdaptorType);
      builder2.CloseComponent();
      }));
      builder.CloseComponent();
      };
  • Setting the datamanager property on the column

  • I even tried setting the ForeignDataSource on the column like this, but still no success:

    • column.ForeignDataSource = new List
      {
      new AvailabilityStatusModel()
      {
      Id = 1,
      Description = ":D"
      },
      new AvailabilityStatusModel()
      {
      Id = 2,
      Description = ":P"
      },
      };

Isthis even possible to achieve?Oris there another(better) way to achieve what i am trying to achieve?


5 Replies 1 reply marked as answer

VN Vignesh Natarajan Syncfusion Team December 16, 2021 09:30 AM UTC

Hi Viktor,  
 
Thanks for contacting Syncfusion support.  
 
Query : “I have made it to work with razor-code (by hardcoding columns) but I am unable to do it in pure C# by generating GridColumns 
 
We understand your requirement to render the ForeignKey column using a C# code not using razor code. We have achieved your requirement using RenderTreeBuilder concept of Blazor. We have defined the generic Grid component using SfGrid class along with ForeignKey column by overriding the BuildRenderTree method. 
 
Refer the below code example.  
 
protected override void BuildRenderTree(RenderTreeBuilder builder) 
{             
    builder.OpenComponent<SfGrid<T>>(0);                
    builder.AddAttribute(1, nameof(AllowPaging), true); 
    builder.AddAttribute(2, nameof(DataSource), DataSource); 
    builder.AddAttribute(3, "ChildContent"new RenderFragment(inner => 
    { 
        //page settings 
        inner.OpenComponent<GridPageSettings>(5); 
        inner.AddAttribute(6, nameof(GridPageSettings.PageSize), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Int32>(10)); 
        inner.CloseComponent(); 
  
        //editsettings  
        inner.OpenComponent<GridEditSettings>(8); 
        inner.AddAttribute(9,"AllowAdding",true); 
        inner.AddAttribute(10, nameof(GridEditSettings.AllowDeleting), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<bool>(true)); 
        inner.AddAttribute(11, nameof(GridEditSettings.AllowEditing), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(true)); 
        inner.CloseComponent(); 
  
        inner.OpenComponent<GridColumns>(12); 
        inner.AddAttribute(13, "ChildContent", (RenderFragment)((_builder1) => 
        { 
  
            _builder1.OpenComponent(14, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
            _builder1.AddAttribute(15, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("OrderID")); 
            _builder1.AddAttribute(16, "IsPrimaryKey", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(true)); 
            _builder1.CloseComponent(); 
            _builder1.AddMarkupContent(17, "\r\n"); 
  
            _builder1.OpenComponent(18, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
            _builder1.AddAttribute(19, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("CustomerID")); 
            _builder1.CloseComponent(); 
            _builder1.AddMarkupContent(21, "\r\n"); 
  
            _builder1.OpenComponent(22, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
            _builder1.AddAttribute(23, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("Freight")); 
            _builder1.CloseComponent(); 
            _builder1.AddMarkupContent(25, "\r\n"); 
             
            _builder1.OpenComponent(26, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
            _builder1.AddAttribute(27, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("OrderDate")); 
            _builder1.CloseComponent(); 
            _builder1.AddMarkupContent(29, "\r\n"); 
  
            _builder1.OpenComponent(30, typeof(GridForeignColumn<T1>)); 
            _builder1.AddAttribute(31, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("EmployeeID")); 
            _builder1.AddAttribute(32, "ForeignKeyValue", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("FirstName")); 
            _builder1.AddAttribute(33, "ChildContent", (RenderFragment)((_builder2) =>  
            { 
                _builder2.OpenComponent<SfDataManager>(34); 
                _builder2.AddAttribute(35, "Adaptor", Syncfusion.Blazor.Adaptors.CustomAdaptor); 
                _builder2.AddAttribute(36, "AdaptorInstance"typeof(CustomAdaptor)); 
                _builder2.CloseComponent(); 
            }));                     
            _builder1.CloseComponent(); 
  
  
        })); 
        inner.CloseComponent(); 
        //grid events 
        inner.OpenComponent<GridEvents<T>>(37); 
        inner.AddAttribute<Syncfusion.Blazor.Grids.RowSelectEventArgs<T>>(38, "RowSelected", 
            EventCallback.Factory.Create<Syncfusion.Blazor.Grids.RowSelectEventArgs<T>>(this, RowSelected)); 
        inner.CloseComponent(); 
  
    })); 
    builder.AddAttribute(39, nameof(Toolbar), new List<string>() {"Add""Edit""Cancel""Update" }); 
    builder.AddComponentReferenceCapture(40, inst => { GridRef = (SfGrid<T>)inst; }); 
    builder.CloseComponent(); 
} 
 
 
Kindly refer the below sample for your reference 
 
 
Please get back to us if you have further queries or if above solution does not resolve your query. 
 
Regards, 
Vignesh Natarajan 


Marked as answer

VI Viktor December 16, 2021 09:19 PM UTC

That worked!

Thanks alot for the assistance with this!


This raises another question.. Why is the component being rendered twice?


I should probably add that I am running Blazor WASM and not Blazor Server.


Best Regards, Viktor



VN Vignesh Natarajan Syncfusion Team December 17, 2021 04:33 AM UTC

Hi Viktor,  
 
Thanks for the update. 
 
Query: “Why is the component being rendered twice? I should probably add that I am running Blazor WASM and not Blazor Server.” 
 
As per your suggestion we have ensured the reported issue with Blazor WASM application and we are unable to reproduce the reported issue at our end. Grid component (Comp) is rendered only once in the webpage. Kindly refer the WASM application from below  
 
 
Kindly share the following details to validate the reported issue further at our end. 
 
  1. Share the Grid code example.
  2. Are you facing script error in browser console. if yes share the screenshot of the issue.
  3. If possible try to reproduce the issue in provided sample and revert back to us.
  4. Or share simple issue reproducible sample.
  5. Are you using any Lifecycle event of Blazor to populate the Generic Grid component.
  6.  Share the video demonstration of the issue you are facing.
 
Above requested details will be very helpful for us to validate the reported query further at our end and provide solution as early as possible.   
 
Regards, 
Vignesh Natarajan  

  




VI Viktor replied to Vignesh Natarajan December 17, 2021 04:59 AM UTC

By Twice I meant that the BuildRenderTree method is called twice.

It rerenders.



VN Vignesh Natarajan Syncfusion Team December 20, 2021 05:05 AM UTC

Hi Viktor,  
 
Thanks for the clarification.  
 
We are able to reproduce the reported behavior at our end also. We suggest you to overcome the reported issue by replacing the SfGrid<T> inheritance with Blazor ComponentBase class. Kindly refer the below code example and modified sample from below  
 
public class Comp<TT1> : ComponentBase 
{ 
    public async Task RowSelected(Syncfusion.Blazor.Grids.RowSelectEventArgs<T> args) 
    { 
        //perform your action here 
    } 
    //take Grid instance 
    private SfGrid<T> GridRef { getset; } 
  
    [Parameter] 
    public IEnumerable<T> Data { getset; } 
  
    protected override void BuildRenderTree(RenderTreeBuilder builder) 
    { 
        Console.WriteLine("TriggerGrid"); 
        builder.OpenComponent<SfGrid<T>>(0); 
        builder.AddAttribute(1, "AllowPaging"true); 
        builder.AddAttribute(2, "DataSource", Data); 
        builder.AddAttribute(3, "ChildContent"new RenderFragment(inner => 
        { 
            //page settings 
            inner.OpenComponent<GridPageSettings>(5); 
            inner.AddAttribute(6, nameof(GridPageSettings.PageSize), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Int32>(10)); 
            inner.CloseComponent(); 
  
            //editsettings  
            inner.OpenComponent<GridEditSettings>(8); 
            inner.AddAttribute(9, "AllowAdding"true); 
            inner.AddAttribute(10, nameof(GridEditSettings.AllowDeleting), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<bool>(true)); 
            inner.AddAttribute(11, nameof(GridEditSettings.AllowEditing), Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(true)); 
            inner.CloseComponent(); 
  
            inner.OpenComponent<GridColumns>(12); 
            inner.AddAttribute(13, "ChildContent", (RenderFragment)((_builder1) => 
            { 
  
                _builder1.OpenComponent(14, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
                _builder1.AddAttribute(15, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("OrderID")); 
                _builder1.AddAttribute(16, "IsPrimaryKey", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Boolean>(true)); 
                _builder1.CloseComponent(); 
                _builder1.AddMarkupContent(17, "\r\n"); 
  
                _builder1.OpenComponent(18, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
                _builder1.AddAttribute(19, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("CustomerID")); 
                _builder1.CloseComponent(); 
                _builder1.AddMarkupContent(21, "\r\n"); 
  
                _builder1.OpenComponent(22, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
                _builder1.AddAttribute(23, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("Freight")); 
                _builder1.CloseComponent(); 
                _builder1.AddMarkupContent(25, "\r\n"); 
  
                _builder1.OpenComponent(26, typeof(Syncfusion.Blazor.Grids.GridColumn)); 
                _builder1.AddAttribute(27, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("OrderDate")); 
                _builder1.CloseComponent(); 
                _builder1.AddMarkupContent(29, "\r\n"); 
  
                _builder1.OpenComponent(30, typeof(GridForeignColumn<T1>)); 
                _builder1.AddAttribute(31, "Field", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("EmployeeID")); 
                _builder1.AddAttribute(32, "ForeignKeyValue", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.String>("FirstName")); 
                _builder1.AddAttribute(33, "ChildContent", (RenderFragment)((_builder2) => 
                { 
                    _builder2.OpenComponent<SfDataManager>(34); 
                    _builder2.AddAttribute(35, "Adaptor", Syncfusion.Blazor.Adaptors.CustomAdaptor); 
                    _builder2.AddAttribute(36, "AdaptorInstance"typeof(CustomAdaptor)); 
                    _builder2.CloseComponent(); 
                })); 
                _builder1.CloseComponent(); 
  
  
            })); 
            inner.CloseComponent(); 
            //grid events 
            inner.OpenComponent<GridEvents<T>>(37); 
            inner.AddAttribute<Syncfusion.Blazor.Grids.RowSelectEventArgs<T>>(38, "RowSelected", 
                EventCallback.Factory.Create<Syncfusion.Blazor.Grids.RowSelectEventArgs<T>>(this, RowSelected)); 
            inner.CloseComponent(); 
  
        })); 
        builder.AddAttribute(39, "Toolbar"new List<string>() { "Add""Edit""Cancel""Update" }); 
        builder.AddComponentReferenceCapture(40, inst => { GridRef = (SfGrid<T>)inst; }); 
        builder.CloseComponent(); 
    } 
} 
 
 
 
Please get back to us if you have further queries.  
 
Regards, 
Vignesh Natarajan  


Loader.
Up arrow icon