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

5级分组下打印单级GroupHeader遇控制台错误求助

解决Radzen WinForms分组表头打印的空引用错误

问题背景

我需要在Windows Forms应用中实现5级分组的GroupHeader打印样式,原打印效果不符合预期。修改模板代码后实现了预期样式,但控制台出现空引用错误。


原代码实现

原GroupHeaderTemplate代码

<GroupHeaderTemplate>
    @if (context.GroupDescriptor.Property == "NomCuenta1" || context.GroupDescriptor.Property == "NomCuenta2")
    {
        <b style="font-weight:bold">@(context.Data.Key ?? "")</b>
    }
    else
    {
        @(context.Data.Key ?? "")
    }
    @{
        var props = typeof(GetBalancePrueba_Result).GetProperties()
        .Where(p =>
        selectedColumns.Contains(p.Name) &&
        (p.PropertyType == typeof(decimal?) ||
        p.PropertyType == typeof(decimal))
        );
        foreach (var prop in props)
        {
            var sum = ((IEnumerable<GetBalancePrueba_Result>)context.Data.Items)
            .Select(x => prop.GetValue(x))
            .Where(v => v != null)
            .Select(v => Convert.ToDecimal(v))
            .Sum();
            <text> | @prop.Name: @sum.ToString("N3")</text>
        }
    }
</GroupHeaderTemplate>

分组配置代码

// Construir la agrupación dinámica basada en los niveles realmente presentes
 var grupos = new System.Collections.ObjectModel.ObservableCollection<Radzen.GroupDescriptor>();
 grupos.Add(new Radzen.GroupDescriptor() { Property = "NomCuenta1", SortOrder = SortOrder.Ascending, FormatString = "{0}" });
 grupos.Add(new Radzen.GroupDescriptor() { Property = "NomCuenta2", SortOrder = SortOrder.Ascending, FormatString = "{0}" });
 grupos.Add(new Radzen.GroupDescriptor() { Property = "NomCuenta3", SortOrder = SortOrder.Ascending, FormatString = "{0}" });
 grupos.Add(new Radzen.GroupDescriptor() { Property = "NomCuenta4", SortOrder = SortOrder.Ascending, FormatString = "{0}" });
 grupos.Add(new Radzen.GroupDescriptor() { Property = "NomCuenta5", SortOrder = SortOrder.Ascending, FormatString = "{0}" });
 // Asignar la nueva estructura de agrupación
 if (grdMain != null)
 {
     grdMain.Groups = grupos;
     StateHasChanged();
 }

修改后出现空引用的代码

<GroupHeaderTemplate>
            @if(!ReportFilterModel.DetallarValue){
                var nomCuenta = context.Data.GetType().GetProperty("NomCuenta1")?.GetValue(context.Data)?.ToString()
                ?? context.Data.GetType().GetProperty("NomCuenta2")?.GetValue(context.Data)?.ToString()
                ?? context.Data.GetType().GetProperty("NomCuenta3")?.GetValue(context.Data)?.ToString()
                ?? context.Data.GetType().GetProperty("NomCuenta4")?.GetValue(context.Data)?.ToString()
                ?? context.Data.GetType().GetProperty("NomCuenta5")?.GetValue(context.Data)?.ToString();
                nomCuenta = nomCuenta ?? "";
                var cuentaPart = nomCuenta.Split('-').FirstOrDefault();
                var nivCta = cuentaPart != null ? cuentaPart.Length == 1 ? 1 : cuentaPart.Length == 2 ? 2 : 0 : 0;
                <b style="font-weight:bold">@context.Data.Key?.ToString() ?? ""</b>
                var props = typeof(GetBalancePrueba_Result).GetProperties()
                .Where(p =>
                selectedColumns.Contains(p.Name) &&
                (p.PropertyType == typeof(decimal?) ||
                p.PropertyType == typeof(decimal))
                );
                foreach (var prop in props)
                {
                    var sum = ((IEnumerable<GetBalancePrueba_Result>)context.Data.Items)
                    .Select(x => prop.GetValue(x))
                    .Where(v => v != null)
                    .Select(v => Convert.ToDecimal(v))
                    .Sum();
                    <text> | @prop.Name: @sum.ToString("N3")</text>
                }
            }
            else
            {
                @if (context.GroupDescriptor.Property == "NomCuenta1" || context.GroupDescriptor.Property == "NomCuenta2")
                {
                    <b style="font-weight:bold">@(context.Data.Key ?? "")</b>
                }
                else
                {
                    @(context.Data.Key ?? "")
                }
                var props = typeof(GetBalancePrueba_Result).GetProperties()
                .Where(p =>
                selectedColumns.Contains(p.Name) &&
                (p.PropertyType == typeof(decimal?) ||
                p.PropertyType == typeof(decimal))
                );
                foreach (var prop in props)
                {
                    var sum = ((IEnumerable<GetBalancePrueba_Result>)context.Data.Items)
                    .Select(x => prop.GetValue(x))
                    .Where(v => v != null)
                    .Select(v => Convert.ToDecimal(v))
                    .Sum();
                    <text> | @prop.Name: @sum.ToString("N3")</text>
                }
            }
        </GroupHeaderTemplate>

错误原因分析

  1. 反射逻辑错误:context.Data是分组容器对象,并非GetBalancePrueba_Result实体,直接通过GetType().GetProperty("NomCuentaX")无法获取目标属性,会返回null触发空引用。
  2. Razor语法错误:@context.Data.Key?.ToString() ?? ""未用括号包裹,Razor解析时会出现表达式识别异常。
  3. 缺少空值校验:未对selectedColumns、context.Data.Items做非空判断,当这些对象为空时直接操作会触发空引用。

修正后的代码

<GroupHeaderTemplate>
    @if(!ReportFilterModel.DetallarValue){
        // 直接通过当前分组的Descriptor获取分组值,无需反射遍历
        var nomCuenta = context.Data.Key?.ToString() ?? "";
        var cuentaPart = nomCuenta.Split('-').FirstOrDefault();
        var nivCta = cuentaPart != null ? cuentaPart.Length == 1 ? 1 : cuentaPart.Length == 2 ? 2 : 0 : 0;
        
        // 修复Razor表达式语法,用括号包裹完整逻辑
        <b style="font-weight:bold">@(context.Data.Key?.ToString() ?? "")</b>
        
        // 先校验selectedColumns是否为空
        if(selectedColumns != null){
            var props = typeof(GetBalancePrueba_Result).GetProperties()
                .Where(p => selectedColumns.Contains(p.Name) && 
                           (p.PropertyType == typeof(decimal?) || p.PropertyType == typeof(decimal)));
            
            foreach (var prop in props)
            {
                // 校验分组Items是否为空,再安全转换类型
                var items = context.Data.Items as IEnumerable<GetBalancePrueba_Result>;
                if(items != null){
                    var sum = items.Select(x => prop.GetValue(x))
                                   .Where(v => v != null)
                                   .Select(v => Convert.ToDecimal(v))
                                   .Sum();
                    <text> | @prop.Name: @sum.ToString("N3")</text>
                }
            }
        }
    }
    else
    {
        @if (context.GroupDescriptor.Property == "NomCuenta1" || context.GroupDescriptor.Property == "NomCuenta2")
        {
            <b style="font-weight:bold">@(context.Data.Key ?? "")</b>
        }
        else
        {
            @(context.Data.Key ?? "")
        }
        
        if(selectedColumns != null){
            var props = typeof(GetBalancePrueba_Result).GetProperties()
                .Where(p => selectedColumns.Contains(p.Name) && 
                           (p.PropertyType == typeof(decimal?) || p.PropertyType == typeof(decimal)));
            
            foreach (var prop in props)
            {
                var items = context.Data.Items as IEnumerable<GetBalancePrueba_Result>;
                if(items != null){
                    var sum = items.Select(x => prop.GetValue(x))
                                   .Where(v => v != null)
                                   .Select(v => Convert.ToDecimal(v))
                                   .Sum();
                    <text> | @prop.Name: @sum.ToString("N3")</text>
                }
            }
        }
    }
</GroupHeaderTemplate>

关键修改说明

  • 简化分组值获取:直接使用context.Data.Key获取当前分组的显示值,替代错误的反射逻辑。
  • 修复Razor语法:将未包裹的表达式用@()包裹,确保Razor正确解析。
  • 增加空值校验:对selectedColumns、context.Data.Items添加非空判断,避免空引用异常。
  • 安全类型转换:用as关键字转换context.Data.Items类型,避免强制转换失败。

内容的提问来源于stack exchange,提问作者Juan Sebastian Rodriguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:50:12