GridMVC循环不适用于动态列名

时间:2018-12-09 14:55:48

标签: c#

在一个项目中,GridMVC被用来生成报告。下面的代码在生成报告的方法中用于服务器端。不幸的是,ReportRowDataContract.cs的设计无法更改(即,顺序编号的ReportData属性)。

编写代码,使得ReportData属性在不同的报表上可以具有不同的数据类型(即,报表A上的ReportData1可以具有字符串的数据类型,而报表B上的ReportData1可以具有整数的数据类型。 ..等等。)。

在ReportGrid.cs的AddGridColumn方法中,有6行使用Column.Add(第一行的注释是第33行,最后一行的注释是第38行。 )。这样做可以,但是我尝试使用循环重构此代码,以在将新的ReportData属性添加到R​​eportRowDataContract.cs时消除对ReportGrid.cs的更新。请参阅以下有关我尝试过的内容和遇到的问题...


这是相关代码-

GridMVC:

using System.Collections.Generic;
using System.Linq;
using GridMvc.Columns;
using GridMvc.Html;
using GridMvc.Pagination;

namespace GridMvc
{
    public class Grid<T> : GridBase<T>, IGrid where T : class
    {
        public Grid(IEnumerable<T> items);
        public Grid(IQueryable<T> items);

        public IGridColumnCollection<T> Columns { get; }
        public bool DefaultFilteringEnabled { get; set; }
        public bool DefaultSortEnabled { get; set; }
        public virtual int DisplayingItemsCount { get; }
        public bool EnablePaging { get; set; }
        public string Language { get; set; }
        public IGridPager Pager { get; set; }
        public GridRenderOptions RenderOptions { get; set; }
        public ISanitizer Sanitizer { get; set; }
        public override IGridSettingsProvider Settings { get; set; }

        public virtual void AutoGenerateColumns();
        protected internal virtual IEnumerable<T> GetItemsToDisplay();
    }
}

ReportRowDataContract.cs:

namespace AcmeCorp.Services.Common.Global
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;


    public class ReportRowDataContract
    {
        public ReportDataDataContract ReportData1 { get; set; }            
        public ReportDataDataContract ReportData2 { get; set; }            
        public ReportDataDataContract ReportData3 { get; set; }            
        public ReportDataDataContract ReportData4 { get; set; }            
        public ReportDataDataContract ReportData5 { get; set; }            
        public ReportDataDataContract ReportData6 { get; set; }

        // an indexed property - for accessing report data properties by index (which is useful for looping)
        public ReportDataDataContract this[int i]
        {
            get
            {
                return new ReportDataDataContract[]
                {
                  ReportData1,
                  ReportData2,
                  ReportData3,
                  ReportData4,
                  ReportData5,
                  ReportData6
                }[i];
            }
        }

        public int GetReportDataPropertyCount()
        {
            return typeof(ReportRowDataContract)
                .GetProperties()
                .Count(p => p.Name.StartsWith("ReportData"));
        }

    }
}

ReportDataDataContract.cs:

namespace AcmeCorp.Services.Common.Global
{
    using System.Runtime.Serialization;

    public class ReportDataDataContract
    {       
        public string Name { get; set; }        
        public string StringValue { get; set; }        
        public decimal? DecimalValue { get; set; }        
        public int? IntValue { get; set; }        
        public bool SumValue { get; set; }        
        public bool AvgValue { get; set; }        
        public int? Index { get; set; }
        public string DisplayFormat { get; set; }       
    }
}

ReportGrid.cs:

namespace AcmeCorp.WebApps.LMS.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using GridMvc;
    using AcmeCorp.Services.Common.Global;

    public class ReportGrid : Grid<ReportRowDataContract>
    {
        public ReportGrid(List<ReportRowDataContract> items) : base(items)
        {
            // get count of how many fields exist in ReportRowDataContract                     
            int reportDataPropertyCount = (new ReportRowDataContract()).GetReportDataPropertyCount();

            // create columns for grid from fields in ReportRowDataContract
            int i = 0;
            while (i + 1 < reportDataPropertyCount)
            {
                AddGridColumn(items[0][i], i);
                i++;
            }
        }

        private void AddGridColumn(ReportDataDataContract reportColumn, int i)
        {
            try
            {
                if (reportColumn != null)
                {
                    if (reportColumn.StringValue != null)
                    {
                             if (i == 0) Columns.Add(m => m.ReportData1.StringValue).Titled(reportColumn.Name); //line #33
                        else if (i == 1) Columns.Add(m => m.ReportData2.StringValue).Titled(reportColumn.Name);
                        else if (i == 2) Columns.Add(m => m.ReportData3.StringValue).Titled(reportColumn.Name);
                        else if (i == 3) Columns.Add(m => m.ReportData4.StringValue).Titled(reportColumn.Name);
                        else if (i == 4) Columns.Add(m => m.ReportData5.StringValue).Titled(reportColumn.Name);
                        else if (i == 5) Columns.Add(m => m.ReportData6.StringValue).Titled(reportColumn.Name); //line #38
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

    }

}

我的重构尝试-用以下代码替换第33至38行:

Columns.Add(m => (new ReportDataDataContract()).StringValue).Titled(reportColumn.Name); //line #33
Columns.GetByName("StringValue").Name = "ReportData" + (i + 1).ToString() + ".StringValue"; //line #34

在调试模式下,第一次经过reportColumn.StringValue != null循环时,当光标悬停在第33行的Columns上方时,名称显示为“ StringValue”。在执行第34行并将光标悬停在Columns上之后,名称显示为“ ReportData1.StringValue”。但是,在此循环的第二次传递中引发了异常。异常对象详细信息-
消息:“网格中已存在列'StringValue'”
来源:“ GridMVC”
堆栈跟踪:    在GridMvc.Columns.GridColumnCollection 1.Add(IGridColumn 1列处)
   在GridMvc.Columns.GridColumnCollection 1.Add[TKey](Expression 1约束处,布尔值隐藏)
   在GridMvc.Columns.GridColumnCollection 1.Add[TKey](Expression 1约束处)
   在C:\ Source \ AcmeCorp \ AcmeCorp.WebApps \ AcmeCorp.WebApps.LMS \ Models \ ReportGrid.cs:第33行中的AcmeCorp.WebApps.LMS.Models.ReportGrid.AddGridColumn(ReportDataDataContract reportColumn,Int32 i) / p>

这似乎是在重命名该列不会摆脱该列的原始名称。为什么不重命名Column工作?如何通过循环使其添加到GridMVC的其他列?

1 个答案:

答案 0 :(得分:0)

找到了解决方案。以此替换第33至38行即可解决此问题:

Columns.Add(m => (new ReportDataDataContract()).StringValue, "ReportData" + (i + 1).ToString() + ".StringValue").Titled(reportColumn.Name);

此处https://archive.codeplex.com/?p=gridmvc的“带有动态列的Grid.MVC”是解决这一问题的关键。在示例代码中,它是在括号中命名包含lambda表达式的列。