diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 7cd72f5e423d4caa961ea6fb8e53de63fc456037..b9c0d8d28559f6d95707bf4c3d177bc353fc869d 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 5.16.1 + 5.16.2 diff --git a/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicContext.cs b/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicContext.cs index 0057821ffbb7af54f148ee3b62782d26097c4ee7..12e0aeab0043370757ec5fd90c9a9db169b389d5 100644 --- a/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicContext.cs +++ b/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicContext.cs @@ -286,6 +286,7 @@ namespace BootstrapBlazor.Components if (Caches.TryGetValue(item.DynamicObjectPrimaryKey, out var cacheItem)) { cacheItem.Row[column.GetFieldName()] = val; + Items = null; } return Task.CompletedTask; } diff --git a/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicObject.cs b/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicObject.cs index ce6da45b21d07e1cae24d15f3e621d10be86bb94..1ab1908b9054178f4c98d84107bbe3cf83eceb4a 100644 --- a/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicObject.cs +++ b/src/BootstrapBlazor/Components/Table/Dynamic/DataTableDynamicObject.cs @@ -3,6 +3,7 @@ // Website: https://www.blazor.zone or https://argozhang.github.io/ using System.Data; +using System.Linq; namespace BootstrapBlazor.Components { @@ -28,7 +29,7 @@ namespace BootstrapBlazor.Components { ret = Row[propertyName]; } - return ret; + return ret ?? LambdaExtensions.GetPropertyValue(this, propertyName); } /// diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs index 3f021d1a29d4a6e2675c4b77f39770a54b9ea0e8..972469ebe25a425b3717966c4eee49d7673b526e 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs @@ -228,7 +228,7 @@ namespace BootstrapBlazor.Components /// public async Task AddAsync() { - if (IsExcel) + if (IsExcel || DynamicContext != null) { await AddDynamicOjbectExcelModelAsync(); } @@ -333,7 +333,7 @@ namespace BootstrapBlazor.Components /// public async Task EditAsync() { - if (UseInjectDataService || IsTracking || OnSaveAsync != null) + if (UseInjectDataService || IsTracking || OnSaveAsync != null || DynamicContext != null) { if (SelectedItems.Count == 1) { @@ -425,7 +425,13 @@ namespace BootstrapBlazor.Components protected async Task SaveModelAsync(EditContext context, ItemChangedType changedType) { var valid = false; - if (OnSaveAsync != null) + if (DynamicContext != null) + { + await DynamicContext.SetValue(context.Model); + RowItemsCache = null; + valid = true; + } + else if (OnSaveAsync != null) { valid = await OnSaveAsync((TItem)context.Model, changedType); } @@ -455,7 +461,7 @@ namespace BootstrapBlazor.Components /// protected async Task SaveAsync(EditContext context, ItemChangedType changedType) { - if (UseInjectDataService || OnSaveAsync != null) + if (UseInjectDataService || OnSaveAsync != null || DynamicContext != null) { await ToggleLoading(true); if (await SaveModelAsync(context, changedType)) diff --git a/src/BootstrapBlazor/Extensions/DynamicObjectContextExtensions.cs b/src/BootstrapBlazor/Extensions/DynamicObjectContextExtensions.cs index 673fa2be76dd2bd12ee235adecd8c5a623221168..0d84b7f667a71c8781ac69d36e30dc58765cd01a 100644 --- a/src/BootstrapBlazor/Extensions/DynamicObjectContextExtensions.cs +++ b/src/BootstrapBlazor/Extensions/DynamicObjectContextExtensions.cs @@ -6,7 +6,9 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Reflection; +using System.Threading.Tasks; namespace BootstrapBlazor.Components { @@ -88,5 +90,25 @@ namespace BootstrapBlazor.Components var type = typeof(DescriptionAttribute); context.AddAttribute(columnName, type, new Type[] { typeof(string) }, new object?[] { description }); } + + /// + /// 扩展方法将指定模型赋值给 context 实例 + /// + /// DynamicObjectContext 实例 + /// 模型实例 + public static async Task SetValue(this IDynamicObjectContext context, object model) + { + if (model is IDynamicObject v) + { + var item = context.GetItems().FirstOrDefault(i => i.DynamicObjectPrimaryKey == v.DynamicObjectPrimaryKey); + if (item != null && context.OnValueChanged != null) + { + foreach (var col in context.GetColumns()) + { + await context.OnValueChanged(item, col, v.GetValue(col.GetFieldName())); + } + } + } + } } } diff --git a/src/BootstrapBlazor/Extensions/LambdaExtensions.cs b/src/BootstrapBlazor/Extensions/LambdaExtensions.cs index 727a3c7de2764e807897078bad2c79cac0bcbbc2..588ec228171b86b4c8c51592d098d54ad4462094 100644 --- a/src/BootstrapBlazor/Extensions/LambdaExtensions.cs +++ b/src/BootstrapBlazor/Extensions/LambdaExtensions.cs @@ -382,7 +382,7 @@ namespace System.Linq return Expression.Lambda>(body, param_p1, param_p2); } - private static readonly ConcurrentDictionary<(Type ModelType, string FieldName), Func> PropertyValueInvokerCache = new(); + private static readonly ConcurrentDictionary<(Type ModelType, string FieldName), Func> PropertyValueInvokerCache = new(); /// /// 获取 指定对象的属性值 @@ -390,11 +390,27 @@ namespace System.Linq /// /// /// - public static object GetPropertyValue(object model, string fieldName) + public static object? GetPropertyValue(object model, string fieldName) { - var cacheKey = (model.GetType(), fieldName); - var invoker = PropertyValueInvokerCache.GetOrAdd(cacheKey, key => GetPropertyValueLambda(model, key.FieldName).Compile()); - return invoker.Invoke(model); + return model.GetType().Assembly.IsDynamic ? ReflectionInvoke() : LambdaInvoke(); + + object? ReflectionInvoke() + { + object? ret = null; + var propertyInfo = model.GetType().GetProperties().FirstOrDefault(i => i.Name == fieldName); + if (propertyInfo != null) + { + ret = propertyInfo.GetValue(model); + } + return ret; + } + + object? LambdaInvoke() + { + var cacheKey = (model.GetType(), fieldName); + var invoker = PropertyValueInvokerCache.GetOrAdd(cacheKey, key => GetPropertyValueLambda(model, key.FieldName).Compile()); + return invoker.Invoke(model); + } } #region TryParse