by Anonymous » 27 Jan 2025, 10:55
Ich habe eine benutzerdefinierte Spaltenkomponente in meinem Mudblazor -DataGrid erstellt, um Daten dynamisch anzuzeigen und die Sortierung zu aktivieren, die wie erwartet funktioniert. Wenn ich jedoch versuche, die Filterung dieser Spalten anzuwenden, begegne ich einen Fehler: "Instanzeigenschaft 'Name' ist nicht für Typ 'System' System.Object '" definiert. Die Spalte verwendet eine PropertyExpression, um dynamisch Lambda -Ausdrücke für den Zugriff auf Eigenschaften zu generieren. Während dies für die Sortierung funktioniert, fehlschlägt sie während der Filterung, da die Daten als System.Object behandelt werden. Mein Muddatagrid ist mit dynamisch generierten Typen mit System.reflection.emit konfiguriert. Ich suche nach einer Lösung, um Filterfilterfilterfilterfilterfest mit diesen dynamischen Spalten oder einem alternativen Ansatz zur Lösung des Problems < /p>
zu beheben
Code: Select all
Unhandled exception in circuit 'ZrG_nxlCYQm_E9s02ePEHPq3brotbidZKxPtIHYph_0'.
System.ArgumentException: Instance property 'Name' is not defined for type 'System.Object' (Parameter 'propertyName')
at System.Linq.Expressions.Expression.Property(Expression expression, String propertyName)
at CustomColumnDemo.Components.Pages.DynamicData.CustomColumn`1.get_PropertyExpression() in D:\C#\CustomColumnDemo\CustomColumnDemo\Components\Pages\DynamicData\CustomColumn.cs:line 36
at MudBlazor.FilterDefinition`1.GenerateFilterFunction(FilterOptions filterOptions)
at MudBlazor.MudDataGrid`1.get_FilteredItems()
at MudBlazor.MudDataGrid`1.get_CurrentPageItems()
at MudBlazor.MudDataGrid`1.b__520_6(RenderTreeBuilder __builder3)
at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at MudBlazor.MudDropContainer`1.b__94_0(RenderTreeBuilder __builder2)
at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at Microsoft.AspNetCore.Components.CascadingValue`1.Render(RenderTreeBuilder builder)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
Dies ist die Rasiererkomponente
Code: Select all
@if (DynamicProperties != null)
{
@foreach (var property in DynamicProperties)
{
}
}
@code {
private Type dynamicType;
private List dynamicObjects = new();
private List
DynamicProperties = new();
protected override void OnInitialized()
{
// Define dynamic properties
var properties = new Dictionary
{
{ "Name", typeof(string) },
{ "Age", typeof(int) },
{ "Country", typeof(string) }
};
// Create the dynamic type
dynamicType = CreateDynamicType("DynamicClass", properties);
// Save properties for rendering columns
DynamicProperties = dynamicType.GetProperties().ToList();
// Create dynamic objects
dynamicObjects = new List
{
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Alice" }, { "Age", 30 }, { "Country", "USA" } }),
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Bob" }, { "Age", 25 }, { "Country", "Canada" } }),
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Charlie" }, { "Age", 35 }, { "Country", "UK" } })
};
}
private Type CreateDynamicType(string typeName, Dictionary properties)
{
// Dynamic type creation logic
var assemblyName = new AssemblyName("DynamicAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
foreach (var property in properties)
{
var fieldBuilder = typeBuilder.DefineField($"_{property.Key}", property.Value, FieldAttributes.Private);
var propertyBuilder = typeBuilder.DefineProperty(property.Key, PropertyAttributes.HasDefault, property.Value, null);
var getter = typeBuilder.DefineMethod(
$"get_{property.Key}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
property.Value,
Type.EmptyTypes);
var getterIL = getter.GetILGenerator();
getterIL.Emit(OpCodes.Ldarg_0);
getterIL.Emit(OpCodes.Ldfld, fieldBuilder);
getterIL.Emit(OpCodes.Ret);
var setter = typeBuilder.DefineMethod(
$"set_{property.Key}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
null,
new[] { property.Value });
var setterIL = setter.GetILGenerator();
setterIL.Emit(OpCodes.Ldarg_0);
setterIL.Emit(OpCodes.Ldarg_1);
setterIL.Emit(OpCodes.Stfld, fieldBuilder);
setterIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getter);
propertyBuilder.SetSetMethod(setter);
}
return typeBuilder.CreateType();
}
private object CreateDynamicObject(Type dynamicType, Dictionary propertyValues)
{
var instance = Activator.CreateInstance(dynamicType);
foreach (var property in propertyValues)
{
dynamicType.GetProperty(property.Key)?.SetValue(instance, property.Value);
}
return instance;
}
}
Und das ist die benutzerdefinierte Spalte, die ich verwendet habe
Code: Select all
public class CustomColumn : Column
{
[Parameter]
public string Field { get; set; }
[Parameter]
public Type CustomPropertyType { get; set; }
protected override Type PropertyType => CustomPropertyType ?? base.PropertyType;
protected override object CellContent(T item)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = item.GetType().GetProperty(Field);
return property?.GetValue(item);
}
return null;
}
public override string PropertyName => Field;
protected internal virtual LambdaExpression? PropertyExpression {
get
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = Expression.Property(parameter, Field);
var lambda = Expression.Lambda(property, parameter);
return lambda;
}
}
protected override object PropertyFunc(T item)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = item.GetType().GetProperty(Field);
return property?.GetValue(item);
}
return null;
}
protected override void SetProperty(object item, object value)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = typeof(T).GetProperty(Field);
if (property != null && property.CanWrite)
{
property.SetValue(item, value);
}
}
}
}
Ich habe eine benutzerdefinierte Spaltenkomponente in meinem Mudblazor -DataGrid erstellt, um Daten dynamisch anzuzeigen und die Sortierung zu aktivieren, die wie erwartet funktioniert. Wenn ich jedoch versuche, die Filterung dieser Spalten anzuwenden, begegne ich einen Fehler: "Instanzeigenschaft 'Name' ist nicht für Typ 'System' System.Object '" definiert. Die Spalte verwendet eine PropertyExpression, um dynamisch Lambda -Ausdrücke für den Zugriff auf Eigenschaften zu generieren. Während dies für die Sortierung funktioniert, fehlschlägt sie während der Filterung, da die Daten als System.Object behandelt werden. Mein Muddatagrid ist mit dynamisch generierten Typen mit System.reflection.emit konfiguriert. Ich suche nach einer Lösung, um Filterfilterfilterfilterfilterfest mit diesen dynamischen Spalten oder einem alternativen Ansatz zur Lösung des Problems < /p>
zu beheben[code] Unhandled exception in circuit 'ZrG_nxlCYQm_E9s02ePEHPq3brotbidZKxPtIHYph_0'.
System.ArgumentException: Instance property 'Name' is not defined for type 'System.Object' (Parameter 'propertyName')
at System.Linq.Expressions.Expression.Property(Expression expression, String propertyName)
at CustomColumnDemo.Components.Pages.DynamicData.CustomColumn`1.get_PropertyExpression() in D:\C#\CustomColumnDemo\CustomColumnDemo\Components\Pages\DynamicData\CustomColumn.cs:line 36
at MudBlazor.FilterDefinition`1.GenerateFilterFunction(FilterOptions filterOptions)
at MudBlazor.MudDataGrid`1.get_FilteredItems()
at MudBlazor.MudDataGrid`1.get_CurrentPageItems()
at MudBlazor.MudDataGrid`1.b__520_6(RenderTreeBuilder __builder3)
at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at MudBlazor.MudDropContainer`1.b__94_0(RenderTreeBuilder __builder2)
at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at Microsoft.AspNetCore.Components.CascadingValue`1.Render(RenderTreeBuilder builder)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
[/code]
[b]Dies ist die Rasiererkomponente[/b]
[code]
@if (DynamicProperties != null)
{
@foreach (var property in DynamicProperties)
{
}
}
@code {
private Type dynamicType;
private List dynamicObjects = new();
private List
DynamicProperties = new();
protected override void OnInitialized()
{
// Define dynamic properties
var properties = new Dictionary
{
{ "Name", typeof(string) },
{ "Age", typeof(int) },
{ "Country", typeof(string) }
};
// Create the dynamic type
dynamicType = CreateDynamicType("DynamicClass", properties);
// Save properties for rendering columns
DynamicProperties = dynamicType.GetProperties().ToList();
// Create dynamic objects
dynamicObjects = new List
{
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Alice" }, { "Age", 30 }, { "Country", "USA" } }),
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Bob" }, { "Age", 25 }, { "Country", "Canada" } }),
CreateDynamicObject(dynamicType, new Dictionary { { "Name", "Charlie" }, { "Age", 35 }, { "Country", "UK" } })
};
}
private Type CreateDynamicType(string typeName, Dictionary properties)
{
// Dynamic type creation logic
var assemblyName = new AssemblyName("DynamicAssembly");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
foreach (var property in properties)
{
var fieldBuilder = typeBuilder.DefineField($"_{property.Key}", property.Value, FieldAttributes.Private);
var propertyBuilder = typeBuilder.DefineProperty(property.Key, PropertyAttributes.HasDefault, property.Value, null);
var getter = typeBuilder.DefineMethod(
$"get_{property.Key}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
property.Value,
Type.EmptyTypes);
var getterIL = getter.GetILGenerator();
getterIL.Emit(OpCodes.Ldarg_0);
getterIL.Emit(OpCodes.Ldfld, fieldBuilder);
getterIL.Emit(OpCodes.Ret);
var setter = typeBuilder.DefineMethod(
$"set_{property.Key}",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
null,
new[] { property.Value });
var setterIL = setter.GetILGenerator();
setterIL.Emit(OpCodes.Ldarg_0);
setterIL.Emit(OpCodes.Ldarg_1);
setterIL.Emit(OpCodes.Stfld, fieldBuilder);
setterIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getter);
propertyBuilder.SetSetMethod(setter);
}
return typeBuilder.CreateType();
}
private object CreateDynamicObject(Type dynamicType, Dictionary propertyValues)
{
var instance = Activator.CreateInstance(dynamicType);
foreach (var property in propertyValues)
{
dynamicType.GetProperty(property.Key)?.SetValue(instance, property.Value);
}
return instance;
}
}
[/code]
[b]Und das ist die benutzerdefinierte Spalte, die ich verwendet habe[/b]
[code] public class CustomColumn : Column
{
[Parameter]
public string Field { get; set; }
[Parameter]
public Type CustomPropertyType { get; set; }
protected override Type PropertyType => CustomPropertyType ?? base.PropertyType;
protected override object CellContent(T item)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = item.GetType().GetProperty(Field);
return property?.GetValue(item);
}
return null;
}
public override string PropertyName => Field;
protected internal virtual LambdaExpression? PropertyExpression {
get
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = Expression.Property(parameter, Field);
var lambda = Expression.Lambda(property, parameter);
return lambda;
}
}
protected override object PropertyFunc(T item)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = item.GetType().GetProperty(Field);
return property?.GetValue(item);
}
return null;
}
protected override void SetProperty(object item, object value)
{
if (item != null && !string.IsNullOrEmpty(Field))
{
var property = typeof(T).GetProperty(Field);
if (property != null && property.CanWrite)
{
property.SetValue(item, value);
}
}
}
}
[/code]