You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:32:33