Я создал собственный столбец в своем DataGrid MudBlazor, который отображает данные и позволяет сортировать их. Но когда C#

Место общения программистов C#
Ответить
Anonymous
 Я создал собственный столбец в своем DataGrid MudBlazor, который отображает данные и позволяет сортировать их. Но когда

Сообщение Anonymous »

Я создал настраиваемый компонент столбца в своем DataGrid MudBlazor для динамического отображения данных и включения сортировки, который работает должным образом. Однако когда я пытаюсь применить фильтрацию к этим столбцам, я сталкиваюсь с ошибкой: «Свойство экземпляра «Имя» не определено для типа «System.Object». Столбец использует PropertyExpression для динамического создания лямбда-выражений для доступа к свойствам, и хотя это работает для сортировки, при фильтрации происходит сбой из-за того, что данные обрабатываются как System.Object. Мой MudDataGrid настроен с использованием динамически генерируемых типов с использованием System.Reflection.Emit. Я ищу решение, обеспечивающее беспрепятственную работу фильтрации с этими динамическими столбцами, или альтернативный подход к решению проблемы.
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)

Это компонент бритвы


@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;
}
}

И это специальный столбец, который я использовал
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);
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... -allows-so
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»