Hi there! I want to create syncfussion datagrid fully dynamically. I'm trying to create a dynamic class that creates properties at runtime instead of hard-coded properties. Please guide me on how can i do that.
What I tried:
//Sp Class
public class Sp : DynamicObject
{
Dictionary<string, object> properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
string name = binder.Name;
return properties.TryGetValue(name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return properties?.Keys;
}
}
//ApplicationDbContext
public class ApplicationDbContext:DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)
{
}
public DbSet<Sp> DisplaySp { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Sp>().HasNoKey();
base.OnModelCreating(modelBuilder);
}
}
//Controller Side
[HttpGet]
[Route("Getspdetails")]
public Task<List<Sp>> GetData()
{
var result = _services.Get();
return result;
}
//Service
public async Task<List<Sp>> Get()
{
var data = _context.DisplaySp.FromSqlRaw("Execute Tbl_DailySaleRpSP @nType = 0,@nsType = 2").ToList();
return data;
}
//Razor Page
<SfGrid DataSource="@Spdetails" AllowPaging="true" AllowFiltering="true" AllowSorting="true">
<GridPageSettings PageSize="10"></GridPageSettings>
<GridAggregates>
<GridAggregate>
<GridAggregateColumns>
@foreach (var col in columns)
{
<GridAggregateColumn Field="@col" Type="AggregateType.Sum">
<FooterTemplate>
@{
var aggregate = (context as AggregateTemplateContext);
<div>
<p>@aggregate?.Sum</p>
</div>
}
</FooterTemplate>
</GridAggregateColumn>
}
</GridAggregateColumns>
</GridAggregate>
</GridAggregates>
</SfGrid>
@code {
public List<Sp> Spdetails { get; set; } = new List<Sp>();
public List<string> columns { get; set; } = new List<string>();
protected override async Task OnInitializedAsync()
{
Spdetails = await Http.GetFromJsonAsync<List<Sp>>("Getspdetails");
if (Spdetails != null && Spdetails.Count > 0) {
PropertyInfo[] props = typeof(Sp).GetProperties();
foreach (var prop in props)
{
if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(double) || prop.PropertyType == typeof(decimal))
{
columns.Add(prop.Name);
}
}
}
}
}
Please look through the code and guide me as right now I'm getting error of "Sequence got no elements".
Hi Muhammad,
Based on your query, we suspect that the columns in your dataset are defined at
runtime. Our grid component is designed to work with strongly typed data
binding, which requires a specific model type (class) for binding. However, we
have alternative options for your scenario. We recommend using either
ExpandoObjectBinding or DynamicObjectBinding. These options allow you to bind
data dynamically when the model type is unknown. For detailed information on
how to use these binding options, please consult the documentation provided
below:
Reference : https://blazor.syncfusion.com/documentation/datagrid/data-binding#expandoobject-binding
https://blazor.syncfusion.com/documentation/datagrid/data-binding#dynamicobject-binding
If we misunderstood your query kindly get back to us.
Regards,
Naveen Palanivel
Hello!
I tried using DynamicObjectBinding and I got "Sequence contains no elements". Please check my code and help me.
Here's my code:
Service side code:
public async Task<IEnumerable<Sp>> Get()
{
var data = await _context.DisplaySp.FromSqlRaw("Execute Tbl_DailySaleRpSP @nType = 0,@nsType = 2").ToArrayAsync();
return data;
}
Controller side code:
[HttpGet]
[Route("Getspdetails")]
public Task<IEnumerable<Sp>> GetData()
{
return _services.Get();
}
Razor page code:
@code {
public List<Sp> Spdetails { get; set; } = new List<Sp>() {};
public List<string> columns { get; set; } = new List<string>() {};
protected override async Task OnInitializedAsync()
{
Spdetails = await Http.GetFromJsonAsync<List<Sp>>("Getspdetails");
if (Spdetails != null && Spdetails.Any())
{
var firstItem = Spdetails[0] as IDictionary<string, object>;
columns = firstItem.Keys.Where(key =>
{
var value = firstItem[key];
return value is int || value is double || value is decimal;
}).ToList();
}
}
}
Before proceeding with the reporting problem, we require some additional clarification from your end. Please share the below details to proceed further at our end.
If possible, a video demonstration of the problem would be greatly appreciated as it can help us identify the issue more effectively.
Above-requested details will be very helpful in validating the reported query at our end and providing a solution as early as possible.