自定义Blazor组件集合渲染前被重置问题排查
Blazor属性网格组件问题修复:属性集合渲染为空问题解决
已解决!排查过程中发现示例代码存在两个低级错误,现已修正并提供可运行示例:
PropertyList组件的Item属性绑定错误:原代码用Item="Blah"传递的是字符串"Blah"而非变量Blah,应改为Item="@Blah"TestClass的属性未添加public修饰符,导致反射无法读取属性值
我开发了一款适配自身需求的类网格Blazor组件,用于展示绑定对象的属性网格,支持自定义要显示的属性及其标题。此前遇到的核心问题是:属性名称集合ListOfProperties在组件渲染时被重置——每个PropertyListItem都会调用AddProperty方法将自身添加到集合,但执行遍历代码时集合为空。
修正后的完整代码
Home.razor
@page "/" @attribute [RenderModeInteractiveServer] @using BlazorApp1.Components.CustomComponents <PageTitle>Home</PageTitle> <h1>Hello, world!</h1> <div class="container"> <PropertyList Item="@Blah"> <PropertyListItem Title="First Name" PropertyName="FirstName"></PropertyListItem> <PropertyListItem Title="Last Name" PropertyName="LastName"></PropertyListItem> <PropertyListItem Title="Bool Value" PropertyName="BoolValue"></PropertyListItem> <PropertyListItem Title="Int Value" PropertyName="IntValue"></PropertyListItem> </PropertyList> </div> @code { private TestClass? Blah = null; protected override void OnInitialized() { Blah = new(); base.OnInitialized(); } public class TestClass { public string TestProperty { get; set; } = "Test"; public string FirstName { get; set; } = "John"; public string LastName { get; set; } = "Doe"; public bool BoolValue { get; set; } = true; public int IntValue { get; set; } = 123; public string IngoreMe { get; set; } = "Ignore Me"; } }
PropertyListItem.razor
@code { [Parameter] public string? Title { get; set; } = ""; [Parameter] public string? PropertyName { get; set; } = ""; [Parameter] public bool HideIfEmpty { get; set; } = true; [Parameter] public bool Visible { get; set; } = true; [CascadingParameter] private PropertyList? Parent { get; set; } protected override void OnInitialized() { if (Parent == null) { throw new ArgumentNullException(nameof(Parent), "List Item must exist within a Property List Control"); } Parent.AddProperty(this); base.OnInitialized(); } }
PropertyList.razor
<CascadingValue Value="this"> @ChildContent </CascadingValue> @if (Item is not null && ListOfProperties is not null) { string rowCss = ""; string itemValue = ""; int rowCount = 0; foreach (var propertyItem in ListOfProperties) { if (propertyItem.Visible == false || string.IsNullOrEmpty(propertyItem.Title)) { continue; } if (propertyItem.HideIfEmpty) { itemValue = GetPropertyValue(Item, propertyItem.PropertyName!); if (string.IsNullOrEmpty(itemValue)) { continue; } } rowCount++; rowCss = rowCount % 2 == 0 ? EvenRowCss : OddRowCss; <div class="row @rowCss"> <div class="col-6"> @propertyItem.Title </div> <div class="col-6"> @GetPropertyValue(Item, propertyItem.PropertyName!) </div> </div> } } else { @EmptyListText } @code { [Parameter] public RenderFragment? ChildContent { get; set; } [Parameter] public object? Item { get; set; } [Parameter] public string EmptyListText { get; set; } = "No items to display"; [Parameter] public string? LabelCss { get; set; } = "fw-bolder"; [Parameter] public int LabelWidth { get; set; } = 4; [Parameter] public string? ValueCss { get; set; } [Parameter] public int ValueWidth { get; set; } = 8; [Parameter] public string EvenRowCss { get; set; } = "bg-light"; [Parameter] public string OddRowCss { get; set; } = ""; private List<PropertyListItem> ListOfProperties = new(); protected override void OnAfterRender(bool firstRender) { if (firstRender) { InvokeAsync(StateHasChanged); } base.OnAfterRender(firstRender); } internal void AddProperty(PropertyListItem p_item) { ListOfProperties.Add(p_item); } private string ConvertBoolToText(bool p_value, string p_trueString, string p_falseString) { return p_value ? p_trueString : p_falseString; } private string GetPropertyValue(object p_item, string p_propertyName) { if (p_item is null || string.IsNullOrEmpty(p_propertyName)) { return ""; } var bf = System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance; var property = p_item.GetType().GetProperty(p_propertyName, bf); if (property is null) { return ""; } var value = property.GetValue(p_item); return value?.ToString() ?? ""; } }
内容的提问来源于stack exchange,提问作者Brien King
相关产品推荐
相关产品推荐

