Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup Condition="'$(VisualStudioVersion)' == '17.0'">
<Version>9.11.5-beta02</Version>
<Version>9.11.5-beta03</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(VisualStudioVersion)' == '18.0'">
<Version>10.0.0-rc.2.1.1</Version>
<Version>10.0.0-rc.2.1.2</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ public partial class EditorForm<TModel> : IShowLabel
[Parameter]
public bool IsDisplay { get; set; }

/// <summary>
/// 获得/设置 是否显示 Display 组件的 Tooltip 默认为 false
/// </summary>
[Parameter]
public bool IsShowDisplayTooltip { get; set; }

/// <summary>
/// 获得/设置 是否使用 SearchTemplate 默认 false 使用 EditTemplate 模板
/// </summary>
Expand Down Expand Up @@ -280,7 +286,7 @@ private RenderFragment AutoGenerateTemplate(IEditorItem item) => builder =>
{
if (IsDisplay || !item.CanWrite(typeof(TModel), ItemChangedType, IsSearch.Value))
{
builder.CreateDisplayByFieldType(item, Model);
builder.CreateDisplayByFieldType(item, Model, IsShowDisplayTooltip);
}
else
{
Expand Down
165 changes: 93 additions & 72 deletions src/BootstrapBlazor/Utils/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,11 @@ internal static IEnumerable<ITableColumn> OrderFunc(this List<ITableColumn> cols
/// <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)
/// <param name="builder"><see cref="RenderTreeBuilder"/> 实例</param>
/// <param name="item"><see cref="IEditorItem"/> 实例</param>
/// <param name="model">当前模型对象实例</param>
/// <param name="showTooltip">如果是 <see cref="Display{TValue}"/> 组件时是否显示提示栏 默认 false</param>
public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEditorItem item, object model, bool showTooltip = false)
{
var fieldType = item.PropertyType;
var fieldName = item.GetFieldName();
Expand All @@ -403,60 +404,80 @@ public static void CreateDisplayByFieldType(this RenderTreeBuilder builder, IEdi
var type = (Nullable.GetUnderlyingType(fieldType) ?? fieldType);
if (type == typeof(bool) || fieldValue?.GetType() == typeof(bool))
{
builder.OpenComponent<Switch>(0);
builder.AddAttribute(10, nameof(Switch.Value), fieldValue);
builder.AddAttribute(20, nameof(Switch.IsDisabled), true);
builder.AddAttribute(30, nameof(Switch.DisplayText), displayName);
builder.AddAttribute(40, nameof(Switch.ShowLabelTooltip), item.ShowLabelTooltip);
if (item is ITableColumn col)
{
builder.AddAttribute(50, "class", col.CssClass);
}
builder.AddMultipleAttributes(60, item.ComponentParameters);
builder.RenderSwitch(item, fieldValue, displayName);
}
else if (item.ComponentType == typeof(Textarea) || item.Rows > 0)
{
builder.OpenComponent(0, typeof(Textarea));
builder.AddAttribute(10, nameof(Textarea.DisplayText), displayName);
builder.AddAttribute(20, nameof(Textarea.Value), fieldValue);
builder.AddAttribute(30, nameof(Textarea.ShowLabelTooltip), item.ShowLabelTooltip);
builder.AddAttribute(40, "readonly", true);
if (item.Rows > 0)
{
builder.AddAttribute(50, "rows", item.Rows);
}
if (item is ITableColumn col)
{
builder.AddAttribute(60, "class", col.CssClass);
}
builder.AddMultipleAttributes(70, item.ComponentParameters);
builder.RenderTextarea(item, fieldValue, displayName);
}
else
{
builder.OpenComponent(0, typeof(Display<>).MakeGenericType(fieldType));
builder.AddAttribute(10, nameof(Display<string>.DisplayText), displayName);
builder.AddAttribute(20, nameof(Display<string>.Value), fieldValue);
builder.AddAttribute(30, nameof(Display<string>.Lookup), item.Lookup);
builder.AddAttribute(30, nameof(Display<string>.LookupService), item.LookupService);
builder.AddAttribute(40, nameof(Display<string>.LookupServiceKey), item.LookupServiceKey);
builder.AddAttribute(50, nameof(Display<string>.LookupServiceData), item.LookupServiceData);
builder.AddAttribute(60, nameof(Display<string>.LookupStringComparison), item.LookupStringComparison);
builder.AddAttribute(65, nameof(Display<string>.ShowLabelTooltip), item.ShowLabelTooltip);
if (item is ITableColumn col)
builder.RenderDisplay(item, fieldType, fieldValue, displayName, showTooltip);
}
}

private static void RenderTextarea(this RenderTreeBuilder builder, IEditorItem item, object? fieldValue, string? displayName)
{
builder.OpenComponent(0, typeof(Textarea));
builder.AddAttribute(10, nameof(Textarea.DisplayText), displayName);
builder.AddAttribute(20, nameof(Textarea.Value), fieldValue);
builder.AddAttribute(30, nameof(Textarea.ShowLabelTooltip), item.ShowLabelTooltip);
builder.AddAttribute(40, "readonly", true);

if (item.Rows > 0)
{
builder.AddAttribute(50, "rows", item.Rows);
}
if (item is ITableColumn col)
{
builder.AddAttribute(60, "class", col.CssClass);
}
builder.AddMultipleAttributes(70, item.ComponentParameters);
builder.CloseComponent();
}

private static void RenderSwitch(this RenderTreeBuilder builder, IEditorItem item, object? fieldValue, string? displayName)
{
builder.OpenComponent<Switch>(0);
builder.AddAttribute(10, nameof(Switch.Value), fieldValue);
builder.AddAttribute(20, nameof(Switch.IsDisabled), true);
builder.AddAttribute(30, nameof(Switch.DisplayText), displayName);
builder.AddAttribute(40, nameof(Switch.ShowLabelTooltip), item.ShowLabelTooltip);

if (item is ITableColumn col)
{
builder.AddAttribute(50, "class", col.CssClass);
}
builder.AddMultipleAttributes(60, item.ComponentParameters);
builder.CloseComponent();
}

private static void RenderDisplay(this RenderTreeBuilder builder, IEditorItem item, Type fieldType, object? fieldValue, string? displayName, bool showTooltip)
{
builder.OpenComponent(0, typeof(Display<>).MakeGenericType(fieldType));
builder.AddAttribute(10, nameof(Display<>.DisplayText), displayName);
builder.AddAttribute(20, nameof(Display<>.Value), fieldValue);
builder.AddAttribute(30, nameof(Display<>.Lookup), item.Lookup);
builder.AddAttribute(35, nameof(Display<>.LookupService), item.LookupService);
builder.AddAttribute(40, nameof(Display<>.LookupServiceKey), item.LookupServiceKey);
builder.AddAttribute(50, nameof(Display<>.LookupServiceData), item.LookupServiceData);
builder.AddAttribute(60, nameof(Display<>.LookupStringComparison), item.LookupStringComparison);
builder.AddAttribute(65, nameof(Display<>.ShowLabelTooltip), item.ShowLabelTooltip);
builder.AddAttribute(66, nameof(Display<>.ShowTooltip), showTooltip);

if (item is ITableColumn col)
{
if (col.Formatter != null)
{
if (col.Formatter != null)
{
builder.AddAttribute(70, nameof(Display<string>.FormatterAsync), CacheManager.GetFormatterInvoker(fieldType, col.Formatter));
}
else if (!string.IsNullOrEmpty(col.FormatString))
{
builder.AddAttribute(80, nameof(Display<string>.FormatString), col.FormatString);
}
builder.AddAttribute(90, "class", col.CssClass);
builder.AddAttribute(70, nameof(Display<>.FormatterAsync), CacheManager.GetFormatterInvoker(fieldType, col.Formatter));
}
else if (!string.IsNullOrEmpty(col.FormatString))
{
builder.AddAttribute(80, nameof(Display<>.FormatString), col.FormatString);
}
builder.AddMultipleAttributes(100, item.ComponentParameters);
builder.AddAttribute(90, "class", col.CssClass);
}

builder.AddMultipleAttributes(100, item.ComponentParameters);
builder.CloseComponent();
}

Expand Down Expand Up @@ -484,31 +505,31 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co
builder.OpenComponent(0, componentType);
if (componentType.IsSubclassOf(typeof(ValidateBase<>).MakeGenericType(fieldType)))
{
builder.AddAttribute(10, nameof(ValidateBase<string>.DisplayText), displayName);
builder.AddAttribute(20, nameof(ValidateBase<string>.Value), fieldValue);
builder.AddAttribute(30, nameof(ValidateBase<string>.ValueChanged), fieldValueChanged);
builder.AddAttribute(40, nameof(ValidateBase<string>.ValueExpression), valueExpression);
builder.AddAttribute(41, nameof(ValidateBase<string>.ShowRequired), GetRequired(item, changedType));
builder.AddAttribute(42, nameof(ValidateBase<string>.RequiredErrorMessage), item.RequiredErrorMessage);
builder.AddAttribute(10, nameof(ValidateBase<>.DisplayText), displayName);
builder.AddAttribute(20, nameof(ValidateBase<>.Value), fieldValue);
builder.AddAttribute(30, nameof(ValidateBase<>.ValueChanged), fieldValueChanged);
builder.AddAttribute(40, nameof(ValidateBase<>.ValueExpression), valueExpression);
builder.AddAttribute(41, nameof(ValidateBase<>.ShowRequired), GetRequired(item, changedType));
builder.AddAttribute(42, nameof(ValidateBase<>.RequiredErrorMessage), item.RequiredErrorMessage);

if (!item.CanWrite(model.GetType(), changedType, isSearch))
{
builder.AddAttribute(50, nameof(ValidateBase<string>.IsDisabled), true);
builder.AddAttribute(50, nameof(ValidateBase<>.IsDisabled), true);
}

if (item.ValidateRules != null)
{
builder.AddAttribute(60, nameof(ValidateBase<string>.ValidateRules), item.ValidateRules);
builder.AddAttribute(60, nameof(ValidateBase<>.ValidateRules), item.ValidateRules);
}

if (item.ShowLabelTooltip != null)
{
builder.AddAttribute(70, nameof(ValidateBase<string>.ShowLabelTooltip), item.ShowLabelTooltip);
builder.AddAttribute(70, nameof(ValidateBase<>.ShowLabelTooltip), item.ShowLabelTooltip);
}

if (skipValidate is true)
{
builder.AddAttribute(71, nameof(ValidateBase<string>.SkipValidate), true);
builder.AddAttribute(71, nameof(ValidateBase<>.SkipValidate), true);
}
}

Expand All @@ -525,31 +546,31 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co

if (IsCheckboxList(fieldType, componentType) && item.Items != null)
{
builder.AddAttribute(90, nameof(CheckboxList<IEnumerable<string>>.Items), item.Items.Clone());
builder.AddAttribute(90, nameof(CheckboxList<>.Items), item.Items.Clone());
}

// Nullable<bool?>
if (item.ComponentType == typeof(Select<bool?>) && fieldType == typeof(bool?) && !item.IsLookup() && item.Items == null)
{
builder.AddAttribute(100, nameof(Select<bool?>.Items), GetNullableBoolItems(model, fieldName));
builder.AddAttribute(100, nameof(Select<>.Items), GetNullableBoolItems(model, fieldName));
}

// Lookup
if (item.IsLookup() && item.Items == null)
{
builder.AddAttribute(110, nameof(Select<SelectedItem>.ShowSearch), item.ShowSearchWhenSelect);
builder.AddAttribute(115, nameof(Select<SelectedItem>.Items), item.Lookup);
builder.AddAttribute(120, nameof(Select<SelectedItem>.LookupService), lookupService);
builder.AddAttribute(121, nameof(Select<SelectedItem>.LookupServiceKey), item.LookupServiceKey);
builder.AddAttribute(122, nameof(Select<SelectedItem>.LookupServiceData), item.LookupServiceData);
builder.AddAttribute(130, nameof(Select<SelectedItem>.StringComparison), item.LookupStringComparison);
builder.AddAttribute(110, nameof(Select<>.ShowSearch), item.ShowSearchWhenSelect);
builder.AddAttribute(115, nameof(Select<>.Items), item.Lookup);
builder.AddAttribute(120, nameof(Select<>.LookupService), lookupService);
builder.AddAttribute(121, nameof(Select<>.LookupServiceKey), item.LookupServiceKey);
builder.AddAttribute(122, nameof(Select<>.LookupServiceData), item.LookupServiceData);
builder.AddAttribute(130, nameof(Select<>.StringComparison), item.LookupStringComparison);
}

// 增加非枚举类,手动设定 ComponentType 为 Select 并且 Items 有值 自动生成下拉框
if (item.Items != null && item.ComponentType == typeof(Select<>).MakeGenericType(fieldType))
{
builder.AddAttribute(140, nameof(Select<SelectedItem>.Items), item.Items.Clone());
builder.AddAttribute(150, nameof(Select<SelectedItem>.ShowSearch), item.ShowSearchWhenSelect);
builder.AddAttribute(140, nameof(Select<>.Items), item.Items.Clone());
builder.AddAttribute(150, nameof(Select<>.ShowSearch), item.ShowSearchWhenSelect);
}

// 设置 SkipValidate 参数
Expand All @@ -563,9 +584,9 @@ public static void CreateComponentByFieldType(this RenderTreeBuilder builder, Co
builder.AddMultipleAttributes(180, item.ComponentParameters);

// 设置 IsPopover
if (componentType.GetPropertyByName(nameof(Select<string>.IsPopover)) != null)
if (componentType.GetPropertyByName(nameof(Select<>.IsPopover)) != null)
{
builder.AddAttribute(190, nameof(Select<string>.IsPopover), item.IsPopover);
builder.AddAttribute(190, nameof(Select<>.IsPopover), item.IsPopover);
}
builder.CloseComponent();
}
Expand Down Expand Up @@ -825,7 +846,7 @@ public static string Format(object? source, IFormatProvider provider)
var instance = Activator.CreateInstance(typeof(List<>).MakeGenericType(t));
if (instance != null)
{
var mi = instance.GetType().GetMethod(nameof(List<string>.AddRange));
var mi = instance.GetType().GetMethod(nameof(List<>.AddRange));
if (mi != null)
{
mi.Invoke(instance, [value]);
Expand Down
1 change: 1 addition & 0 deletions test/UnitTest/Components/EditorFormTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public void IsDisplay_Ok()
var cut = Context.RenderComponent<EditorForm<Foo>>(pb =>
{
pb.Add(a => a.IsDisplay, true);
pb.Add(a => a.IsShowDisplayTooltip, true);
pb.Add(a => a.Model, foo);
pb.Add(a => a.FieldItems, GenerateEditorItems(foo));
});
Expand Down
Loading