private RenderFragment AutoGenerateTemplate(IEditorItem item) => builder => { var fieldType = item.PropertyType; if (fieldType != null && Model != null) { // GetDisplayName var fieldName = item.GetFieldName(); var displayName = Utility.GetDisplayName(Model, fieldName); // FieldValue var valueInvoker = GetPropertyValueLambdaCache.GetOrAdd((typeof(TModel), fieldName), key => LambdaExtensions.GetPropertyValueLambda <TModel, object?>(Model, key.FieldName).Compile()); var fieldValue = valueInvoker.Invoke(Model); // ValueChanged var valueChangedInvoker = CreateLambda(fieldType).Compile(); var fieldValueChanged = valueChangedInvoker(Model, fieldName); // ValueExpression var body = Expression.Property(Expression.Constant(Model), typeof(TModel), fieldName); var tDelegate = typeof(Func <>).MakeGenericType(fieldType); var valueExpression = Expression.Lambda(tDelegate, body); var index = 0; var componentType = EditorForm <TModel> .GenerateComponent(fieldType); builder.OpenComponent(index++, componentType); builder.AddAttribute(index++, "DisplayText", displayName); builder.AddAttribute(index++, "Value", fieldValue); builder.AddAttribute(index++, "ValueChanged", fieldValueChanged); builder.AddAttribute(index++, "ValueExpression", valueExpression); builder.AddAttribute(index++, "IsDisabled", item.Readonly); builder.AddMultipleAttributes(index++, CreateMultipleAttributes(fieldType, fieldName, item)); builder.CloseComponent(); } };
private RenderFragment AutoGenerateTemplate(IEditorItem item) => builder => { var fieldType = item.PropertyType; if (fieldType != null && Model != null) { var fieldName = item.GetFieldName(); // GetDisplayName // 先取 Text 属性值,然后取资源文件中的值 var displayName = item.GetDisplayName() ?? Utility.GetDisplayName(Model, fieldName); // FieldValue var valueInvoker = GetPropertyValueLambdaCache.GetOrAdd((typeof(TModel), fieldName), key => LambdaExtensions.GetPropertyValueLambda <TModel, object?>(Model, key.FieldName).Compile()); var fieldValue = valueInvoker.Invoke(Model); // ValueChanged var valueChangedInvoker = CreateLambda(fieldType).Compile(); var fieldValueChanged = valueChangedInvoker(Model, fieldName); // ValueExpression var body = Expression.Property(Expression.Constant(Model), typeof(TModel), fieldName); var tDelegate = typeof(Func <>).MakeGenericType(fieldType); var valueExpression = Expression.Lambda(tDelegate, body); if (IsDisplay) { builder.OpenComponent(0, typeof(Display <>).MakeGenericType(fieldType)); builder.AddAttribute(1, "DisplayText", displayName); builder.AddAttribute(2, "Value", fieldValue); builder.AddAttribute(3, "ValueChanged", fieldValueChanged); builder.AddAttribute(4, "ValueExpression", valueExpression); builder.AddAttribute(5, "ShowLabel", ShowLabel ?? true); builder.CloseComponent(); } else { var componentType = item.ComponentType ?? EditorForm <TModel> .GenerateComponent(fieldType, item.Rows != 0); builder.OpenComponent(0, componentType); builder.AddAttribute(1, "DisplayText", displayName); builder.AddAttribute(2, "Value", fieldValue); builder.AddAttribute(3, "ValueChanged", fieldValueChanged); builder.AddAttribute(4, "ValueExpression", valueExpression); builder.AddAttribute(5, "IsDisabled", item.Readonly); if (IsCheckboxList(fieldType) && item.Data != null) { builder.AddAttribute(6, nameof(CheckboxList <IEnumerable <string> > .Items), item.Data); } builder.AddMultipleAttributes(7, CreateMultipleAttributes(fieldType, fieldName, item)); builder.CloseComponent(); } } };
/// <summary> /// RenderTreeBuilder 扩展方法 通过 IEditorItem 与 model 创建 Display 组件 /// </summary> /// <param name="builder"></param> /// <param name="item"></param> /// <param name="model"></param> public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEditorItem item, object model) { var fieldType = item.PropertyType; var fieldName = item.GetFieldName(); var displayName = item.GetDisplayName() ?? GetDisplayName(model, fieldName); var fieldValue = GenerateValue(model, fieldName); var type = (Nullable.GetUnderlyingType(fieldType) ?? fieldType); if (type == typeof(bool) || fieldValue?.GetType() == typeof(bool)) { builder.OpenComponent <Switch>(0); builder.AddAttribute(1, nameof(Switch.Value), fieldValue); builder.AddAttribute(2, nameof(Switch.IsDisabled), true); builder.AddAttribute(3, nameof(Switch.DisplayText), displayName); builder.AddAttribute(4, nameof(Switch.ShowLabelTooltip), item.ShowLabelTooltip); builder.CloseComponent(); } else if (item.ComponentType == typeof(Textarea)) { builder.OpenComponent(0, typeof(Textarea)); builder.AddAttribute(1, nameof(Textarea.DisplayText), displayName); builder.AddAttribute(2, nameof(Textarea.Value), fieldValue); builder.AddAttribute(3, nameof(Textarea.ShowLabelTooltip), item.ShowLabelTooltip); builder.AddAttribute(4, "readonly", true); if (item.Rows > 0) { builder.AddAttribute(5, "rows", item.Rows); } builder.CloseComponent(); } else { builder.OpenComponent(0, typeof(Display <>).MakeGenericType(fieldType)); builder.AddAttribute(1, nameof(Display <string> .DisplayText), displayName); builder.AddAttribute(2, nameof(Display <string> .Value), fieldValue); builder.AddAttribute(3, nameof(Display <string> .LookupServiceKey), item.LookupServiceKey); builder.AddAttribute(4, nameof(Display <string> .ShowLabelTooltip), item.ShowLabelTooltip); builder.CloseComponent(); } }
private static void CreateProperty(this TypeBuilder typeBuilder, IEditorItem col, IEnumerable <CustomAttributeBuilder>?attributeBuilds = null) => CreateProperty(typeBuilder, col.GetFieldName(), col.PropertyType, attributeBuilds);
/// <summary> /// RenderTreeBuilder 扩展方法 通过指定模型与属性生成编辑组件 /// </summary> /// <param name="builder"></param> /// <param name="model"></param> /// <param name="component"></param> /// <param name="item"></param> /// <param name="changedType"></param> /// <param name="isSearch"></param> /// <param name="lookUpService"></param> public static void CreateComponentByFieldType(this RenderTreeBuilder builder, ComponentBase component, IEditorItem item, object model, ItemChangedType changedType = ItemChangedType.Update, bool isSearch = false, ILookupService?lookUpService = null) { var fieldType = item.PropertyType; var fieldName = item.GetFieldName(); var displayName = item.GetDisplayName() ?? GetDisplayName(model, fieldName); var fieldValue = GenerateValue(model, fieldName); var fieldValueChanged = GenerateValueChanged(component, model, fieldName, fieldType); var valueExpression = GenerateValueExpression(model, fieldName, fieldType); var lookup = item.Lookup ?? lookUpService?.GetItemsByKey(item.LookupServiceKey); var componentType = item.ComponentType ?? GenerateComponentType(fieldType, item.Rows != 0, lookup); builder.OpenComponent(0, componentType); if (componentType.IsSubclassOf(typeof(ValidateBase <>).MakeGenericType(fieldType))) { builder.AddAttribute(1, nameof(ValidateBase <string> .DisplayText), displayName); builder.AddAttribute(2, nameof(ValidateBase <string> .Value), fieldValue); builder.AddAttribute(3, nameof(ValidateBase <string> .ValueChanged), fieldValueChanged); builder.AddAttribute(4, nameof(ValidateBase <string> .ValueExpression), valueExpression); if (!item.CanWrite(model.GetType(), changedType, isSearch)) { builder.AddAttribute(5, nameof(ValidateBase <string> .IsDisabled), true); } if (item.ValidateRules != null) { builder.AddAttribute(6, nameof(ValidateBase <string> .ValidateRules), item.ValidateRules); } if (item.ShowLabelTooltip != null) { builder.AddAttribute(7, nameof(ValidateBase <string> .ShowLabelTooltip), item.ShowLabelTooltip); } } if (componentType == typeof(NullSwitch) && TryGetProperty(model.GetType(), fieldName, out var propertyInfo)) { // 读取默认值 var defaultValueAttr = propertyInfo.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttr != null) { var dv = defaultValueAttr.Value is bool v && v; builder.AddAttribute(8, nameof(NullSwitch.DefaultValueWhenNull), dv); } } if (IsCheckboxList(fieldType, componentType) && item.Items != null) { builder.AddAttribute(9, nameof(CheckboxList <IEnumerable <string> > .Items), item.Items.Clone()); } // Nullabl<bool?> if (item.ComponentType == typeof(Select <bool?>) && fieldType == typeof(bool?) && lookup == null && item.Items == null) { builder.AddAttribute(10, nameof(Select <bool?> .Items), GetNullableBoolItems(model, fieldName)); } // Lookup if (lookup != null && item.Items == null) { builder.AddAttribute(11, nameof(Select <SelectedItem> .Items), lookup.Clone()); builder.AddAttribute(12, nameof(Select <SelectedItem> .StringComparison), item.LookupStringComparison); } // 增加非枚举类,手动设定 ComponentType 为 Select 并且 Data 有值 自动生成下拉框 if (item.Items != null && item.ComponentType == typeof(Select <>).MakeGenericType(fieldType)) { builder.AddAttribute(13, nameof(Select <SelectedItem> .Items), item.Items.Clone()); } // 设置 SkipValidate 参数 if (IsValidatableComponent(componentType)) { builder.AddAttribute(14, nameof(IEditorItem.SkipValidate), item.SkipValidate); } builder.AddMultipleAttributes(15, CreateMultipleAttributes(fieldType, model, fieldName, item)); if (item.ComponentParameters != null) { builder.AddMultipleAttributes(16, item.ComponentParameters); } builder.CloseComponent(); }