This is a migrated thread and some comments may be shown as answers.

ExpandoObject as a source of the Grid with Autogenerated columns, raise error

16 Answers 1261 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
Aleksandr asked on 03 Nov 2020, 08:13 PM

any change to make it work, or ability to create pivot?

 

blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Dynamic objects cannot be used with AutoGenerateColumns=true
System.ArgumentException: Dynamic objects cannot be used with AutoGenerateColumns=true
   at Telerik.Blazor.Components.TelerikGrid`1.<OnParametersSetAsync>d__247[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Marin Bratanov
Telerik team
commented on 06 Jan 2022, 03:55 PM

Hello Aleksandr,

To know when a feature is implemented, click the Follow button on its portal page, for example - the one for the pivot grid: https://feedback.telerik.com/blazor/1480716-pivot-grid

I must note that I can't promise a pivot grid will handle expandos, at least in v1, and I very much doubt it will generate columns or dimensions based on them.

With the grid, you should still loop over the deired info and generate the columns that way, we have a sample of that: https://github.com/telerik/blazor-ui/blob/master/grid/binding-to-expando-object/BindingToExpandoObject/Pages/AutoGeneratedColumns.razor

16 Answers, 1 is accepted

Sort by
0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 03 Nov 2020, 08:35 PM

i also checked Datatable approach as a datasource of the grid, seems will not work too due to converting to dictionary on OnRead event

 

i need to build pivot grid based on the data we have, so thу number of columns will be dynamic,  any suggestions?

0
Marin Bratanov
Telerik team
answered on 04 Nov 2020, 08:23 AM

Hi Aleksandr,

A Pivot grid is a very far cry from a regular grid. You can Follow a pivot grid component here: https://feedback.telerik.com/blazor/1480716-pivot-grid.

As for generating columns with expandos - you can do that in a simple loop, see this example: https://github.com/telerik/blazor-ui/blob/master/grid/binding-to-expando-object/BindingToExpandoObject/Pages/AutoGeneratedColumns.razor

The same general approach for "autogenerating" columns from a datatable applies too - you know the field names in the datatable, you can loop over them.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Erna
Top achievements
Rank 1
commented on 06 Jan 2022, 03:40 PM

Hi Marin, i tried to "autogenerate" columns (with code like in AutoGeneratedColumns.razor), but failed to edit in the cell directly. Any suggestions how to edit ExpandoObject directly in GridCell (not with <GridCommandColumn>)?
James
Top achievements
Rank 2
commented on 24 Feb 2023, 08:10 AM

Hi Marin, can we implement the EditorTemplate using ExpandoObjects? I've raised a support ticket as well... 
0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 08:51 AM
great, thx a lot for the reply, is it possible to add references to the gits in help?
0
Marin Bratanov
Telerik team
answered on 04 Nov 2020, 08:55 AM

Hello Aleksandr,

The expando object example is linked from the DataBinding section of the grid: https://docs.telerik.com/blazor-ui/components/grid/overview#data-binding. Do you have something else in mind?

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 09:05 AM
hm, maybe was tired, missed yesterday somehow, thx for reference 
0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 09:56 AM
Marin thx again, works as expected 
0
Marin Bratanov
Telerik team
answered on 04 Nov 2020, 10:08 AM

Glad to see you moving forward, Aleksandr!

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 01:26 PM

Mirin,

 

is filter operations allowed for ExpandoObject source?

<GridColumn Field="@item.Key" FieldType="@typeof(int)" Width="100px" Locked="true"></GridColumn>

 

when i try to filter using standard menu filter 

 

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Specified cast is not valid.
System.InvalidCastException: Specified cast is not valid.
   at System.Linq.Enumerable.WhereListIterator`1[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].GetCount(Boolean onlyIfCheap)
   at System.Linq.Enumerable.Count[ExpandoObject](IEnumerable`1 source)
   at System.Linq.EnumerableExecutor`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Execute()
   at System.Linq.EnumerableQuery`1[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].System.Linq.IQueryProvider.Execute[Int32](Expression expression)
   at Telerik.DataSource.Extensions.QueryableExtensions.Count(IQueryable source)
   at Telerik.DataSource.Extensions.QueryableExtensions.CreateDataSourceResult[Object,Object](IQueryable queryable, DataSourceRequest request, Func`2 selector)
   at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request)
   at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IEnumerable enumerable, DataSourceRequest request)
   at Telerik.Blazor.Data.TelerikDataSourceBase.ProcessData(IEnumerable data)
   at Telerik.Blazor.Components.Common.DataBoundComponent`1[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].ProcessDataInternal()
   at Telerik.Blazor.Components.Common.DataBoundComponent`1.<ProcessDataAsync>d__22[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<DataBoundProcessData>d__345[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<ProcessDataAsync>d__340[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<ApplyFiltersAsync>d__280[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<OnFilterChange>d__278[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Telerik.Blazor.Components.Common.Filters.FilterMenu.TelerikFilterMenu.Filter()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Telerik.Blazor.Components.Common.Filters.FilterMenu.FilterMenuForm.OnFilterClick()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

 

 

 

 

 

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 01:32 PM

same think for custom filter, it just does not find anything

<FilterMenuTemplate>
                           @{
                               <div class="filter-values-container">
                                   @foreach (var fieldValue in @ViewModel.Data.Where(_ => !string.IsNullOrEmpty((string)((IDictionary<string, object>)_)[item.Key])).DistinctBy(_ => (string)((IDictionary<string, object>)_)[item.Key]))
                                   {
                                       var fldV = (string)((IDictionary<string, object>)fieldValue)[item.Key];
                                       <div>
                                           <TelerikCheckBox Value="@(GetFilterValues(context.FilterDescriptor).Contains(fldV))"
                                                            ValueChanged="@((bool value) => ColumnValueChanged(value, fldV, item.Key, context.FilterDescriptor))"
                                                            Id="@($"{item.Key}_{fldV}")">
                                           </TelerikCheckBox>
                                           <label for="@($"{item.Key}_{fldV}")">
                                               @fldV
                                           </label>
                                       </div>
                                   }
                               </div>
                           }
                       </FilterMenuTemplate>

 

same code works fine is we have Types object instead of Expando

0
Marin Bratanov
Telerik team
answered on 04 Nov 2020, 01:35 PM

Hi Aleksandr,

The built-in filtering works, you can compare against the sample project: https://github.com/telerik/blazor-ui/tree/master/grid/binding-to-expando-object to see what's the difference causing issues.

For custom filter tempaltes - it is up to the application code to build correct filters and mismatch between the types will cause errors.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 01:52 PM

yes, for Id GetType shows that is System.Int64, changed to 

<GridColumn Field="@item.Key" FieldType="@typeof(System.Int64)" Width="100px" Locked="true" ></GridColumn>

 

 

started working, for custom invesigating

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 05:08 PM

Marin,

so the problem is in comparison, for standard objects work fine even if we change it to FilterOperator.Contains

filterDescriptor.FilterDescriptors.Add(new FilterDescriptor(columnName, FilterOperator.IsEqualTo, itemValue));

 

 

for expandoObject it will raise the error that the property should be string

 

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Provided expression should have string type (Parameter 'stringExpression')
System.ArgumentException: Provided expression should have string type (Parameter 'stringExpression')
   at Telerik.DataSource.Expressions.ExpressionFactory.LiftStringExpressionToEmpty(Expression stringExpression)
   at Telerik.DataSource.Expressions.FilterOperatorExtensions.GenerateToLowerCall(Expression stringExpression, Boolean liftMemberAccess)
   at Telerik.DataSource.Expressions.FilterOperatorExtensions.GenerateCaseInsensitiveStringMethodCall(MethodInfo methodInfo, Expression left, Expression right, Boolean liftMemberAccess)
   at Telerik.DataSource.Expressions.FilterOperatorExtensions.GenerateContains(Expression left, Expression right, Boolean liftMemberAccess)
   at Telerik.DataSource.Expressions.FilterOperatorExtensions.CreateExpression(FilterOperator filterOperator, Expression left, Expression right, Boolean liftMemberAccess)
   at Telerik.DataSource.Expressions.FilterDescriptorExpressionBuilder.CreateBodyExpression()
   at Telerik.DataSource.FilterDescriptor.CreateFilterExpression(ParameterExpression parameterExpression)
   at Telerik.DataSource.FilterDescriptorBase.CreateFilterExpression(Expression instance)
   at Telerik.DataSource.Expressions.FilterDescriptorCollectionExpressionBuilder.CreateBodyExpression()
   at Telerik.DataSource.CompositeFilterDescriptor.CreateFilterExpression(ParameterExpression parameterExpression)
   at Telerik.DataSource.FilterDescriptorBase.CreateFilterExpression(Expression instance)
   at Telerik.DataSource.Expressions.FilterDescriptorCollectionExpressionBuilder.CreateBodyExpression()
   at Telerik.DataSource.Expressions.FilterExpressionBuilder.CreateFilterExpression()
   at Telerik.DataSource.Extensions.QueryableExtensions.Where(IQueryable source, IEnumerable`1 filterDescriptors)
   at Telerik.DataSource.Extensions.QueryableExtensions.CreateDataSourceResult[Object,Object](IQueryable queryable, DataSourceRequest request, Func`2 selector)
   at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IQueryable queryable, DataSourceRequest request)
   at Telerik.DataSource.Extensions.QueryableExtensions.ToDataSourceResult(IEnumerable enumerable, DataSourceRequest request)
   at Telerik.Blazor.Data.TelerikDataSourceBase.ProcessData(IEnumerable data)
   at Telerik.Blazor.Components.Common.DataBoundComponent`1[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].ProcessDataInternal()
   at Telerik.Blazor.Components.Common.DataBoundComponent`1.<ProcessDataAsync>d__22[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<DataBoundProcessData>d__345[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<ProcessDataAsync>d__340[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<ApplyFiltersAsync>d__280[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Telerik.Blazor.Components.TelerikGrid`1.<OnFilterChange>d__278[[System.Dynamic.ExpandoObject, System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Telerik.Blazor.Components.Common.Filters.FilterMenu.TelerikFilterMenu.Filter()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Telerik.Blazor.Components.Common.Filters.FilterMenu.FilterMenuForm.OnFilterClick()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)

 

any thoughts to make it work?

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 04 Nov 2020, 05:18 PM

here is the solution

 

filterDescriptor.FilterDescriptors.Add(new FilterDescriptor(columnName, FilterOperator.IsEqualTo, itemValue){MemberType = typeof(string)});
0
Accepted
Marin Bratanov
Telerik team
answered on 05 Nov 2020, 11:49 AM

Hello,

I made another example for you: https://github.com/telerik/blazor-ui/blob/master/grid/binding-to-expando-object/BindingToExpandoObject/Pages/CustomFiltering.razor

Setting the MemberType of the FilterDescriptor is always mandatory when you are adding a new one, and it must match the type of the actual object. In the example I made above, its an integer.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
answered on 05 Nov 2020, 01:08 PM
maybe if it is required, would be better to extent Constructor of Filter descriptor? 
0
Marin Bratanov
Telerik team
answered on 05 Nov 2020, 01:42 PM

Here's the feature request I made on your behalf for that that you can Follow: https://feedback.telerik.com/blazor/1493975-add-filterdescriptor-constructor-that-can-also-take-the-membertype

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Grid
Asked by
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
Answers by
Aleksandr
Top achievements
Rank 1
Bronze
Bronze
Veteran
Marin Bratanov
Telerik team
Share this question
or