gpt4 book ai didi

c# - 在 Asp.Net Gridview 中分组数据

转载 作者:行者123 更新时间:2023-12-02 09:40:35 25 4
gpt4 key购买 nike

我有两个存储过程,它们返回两组相关数据。数据是这样的。
第一个过程返回这样的数据

ISSUE_ID          ISSUETYPE          
-------------------------------------
1 ISSUE 1 TYPE
2 ISSUE 2 TYPE
3 ISSUE 3 TYPE
4 ISSUE 4 TYPE

第二个程序根据 ISSUE_ID 返回这样的数据
HEADER ID          HEADER NAME            ISSUE_ID       
-----------------------------------------------------
1 HEADER 1 NAME 1
2 HEADER 2 NAME 1
3 HEADER 3 NAME 2
4 HEADER 4 NAME 2
5 HEADER 5 NAME 3

问题是我如何根据 ISSUE_ID 对其进行分组,并使用两个存储过程在 gridview 中将其分组显示。我在很多论坛上搜索过,我发现选项是嵌套的 gridview。我可以在不使用此嵌套 gridview 的情况下实现此目的吗?

最后我想像这样在gridview中显示。
ISSUE 1 TYPE
-----------------------------
HEADER 1 NAME
HEADER 2 NAME
ISSUE 2 TYPE
-----------------------------
HEADER 3 NAME
HEADER 4 NAME
ISSUE 3 TYPE
-----------------------------
HEADER 5 NAME

提前感谢一百万.. 需要一些建议来实现这一目标。

最佳答案

An example of grouping in ASP.Net GridView


<asp:GridView ID="grdViewOrders" CssClass="serh-grid" runat="server" AutoGenerateColumns="False" 
TabIndex="1" Width="100%" CellPadding="4" ForeColor="Black" GridLines="Vertical"
BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px"
OnRowDataBound="grdViewOrders_RowDataBound" OnRowCommand="grdViewOrders_RowCommand"
OnRowCreated="grdViewOrders_RowCreated">
<Columns>
<asp:BoundField DataField="OrderID" HeaderText="OrderID" SortExpression="OrderID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity" />
<asp:BoundField DataField="Discount" HeaderText="Discount" SortExpression="Discount" />
<asp:BoundField DataField="Amount" HeaderText="Amount" SortExpression="Amount" />
</Columns>
<FooterStyle BackColor="#CCCC99" />
<SelectedRowStyle CssClass="grid-sltrow" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" BorderStyle="Solid" BorderWidth="1px" BorderColor="Black" />
</asp:GridView>

Grouping in ASP.Net GridView

注释:
  • 主要逻辑在GridView的RowCreated和RowDataBound事件中。
  • 在遍历所有行时我是
  • 查看 CustomerId(主索引)并检查其他行。
  • 跟踪正在运行的 GrandTotal(s)
  • 跟踪正在运行的小计
  • 在迭代结果集时,主索引的每一点都会发生变化:
  • 添加小计行
  • 重置小计准备下一组
  • 标题在 GridView 中显示为新行。

  • GridView helper



    使用 GridViewHelper

    下面我们将看到一些 GridViewHelper 示例。首先,我们显示将创建组和摘要的网格。样本数据来自 Northwind 数据库,稍作修改:

    enter image description here

    要为 ItemTotal 列创建摘要,我们只需要 promise 的 2 行代码:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum);
    }

    首先,我们创建 GridViewHelper,设置它将在构造函数中起作用的网格。然后我们注册指定列名和要执行的汇总操作的汇总。结果如下:

    enter image description here

    在此示例中,添加了一个新行以显示摘要。另一种选择是使用页脚行来显示摘要而不是创建一个新摘要。将新行添加到网格时,只会创建显示汇总列所需的单元格。使用页脚创建所有单元格。在组摘要的情况下,生成所有单元格或仅生成所需单元格是组属性。

    现在我们将创建一个组。代码如下所示:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterGroup("ShipRegion", true, true);
    helper.ApplyGroupSort();
    }

    RegisterGroup 方法的第一个参数定义必须为其创建组的列。也可以创建一个复合组,由一组列组成。第二个参数指定组是否是自动的。在这种情况下,将自动为组标题创建一个新行。第三个参数指定是否必须隐藏组列。 ApplyGroupSort 方法将网格的排序表达式设置为组列,在本例中为 ShipRegion。这是分组正常工作所必需的,除非数据来自数据库。

    在上面的示例中,列 ShipRegion 已隐藏:

    enter image description here

    让我们做一些更有趣的事情,让我们为创建的组添加一个摘要。我们只需要多一行就可以将摘要注册到组中:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterGroup("ShipRegion", true, true);
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum, "ShipRegion");
    helper.ApplyGroupSort();
    }

    这一次,RegisterSummary 方法采用另一个参数。该参数指定必须为其创建摘要的组的名称。组名是从组列名自动生成的。如果组只有一列,则组名将是该列的名称。如果组有多个列,组名将是组成组的列的有序串联,并用加号(“+”)连接:“ShipRegion+ShipName”。

    我们可以在带有分组的网格下方看到该组的摘要:

    enter image description here

    可以在网格中创建多个组,模拟分层分组,如下所示:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterGroup("ShipRegion", true, true);
    helper.RegisterGroup("ShipName", true, true);
    helper.ApplyGroupSort();
    }

    结果:

    enter image description here

    当有多个组时,可视化会受到影响。 GridViewHelper 具有允许轻松实现视觉或功能调整的事件。事件列表如下:
  • GroupStart:在新组开始时发生,这意味着在组列中找到新值时。
  • GroupEnd:出现在
  • 组的最后一行
  • GroupHeader:为组添加自动标题行时发生。如果组不是自动的,则不会触发该事件。
  • GroupSummary:为组生成汇总行时发生。如果该组不是自动的,则不会触发该事件,但如果该组是抑制组(稍后会看到),则会触发该事件。
  • GeneralSummary:在计算一般摘要后发生。如果汇总是自动的,则在添加汇总行并将汇总值放置在行中之后发生事件。
  • FooterDataBound:发生在页脚数据绑定(bind)中。

  • 再多写几行代码,我们就可以改善网格的视觉效果:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterGroup("ShipRegion", true, true);
    helper.RegisterGroup("ShipName", true, true);
    helper.GroupHeader += new GroupEvent(helper_GroupHeader);
    helper.ApplyGroupSort();
    }

    private void helper_GroupHeader(string groupName, object[] values, GridViewRow row)
    {
    if ( groupName == "ShipRegion" )
    {
    row.BackColor = Color.LightGray;
    row.Cells[0].Text = "&nbsp;&nbsp;" + row.Cells[0].Text;
    }
    else if (groupName == "ShipName")
    {
    row.BackColor = Color.FromArgb(236, 236, 236);
    row.Cells[0].Text = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + row.Cells[0].Text;
    }
    }

    化妆品后的格子:

    enter image description here

    更多分组选项

    还有两个更有趣的例子。第一个提出了一个复合组。第二个定义了一个抑制组,它具有与 sql GROUP BY 子句相同的行为。重复值被抑制,并对其他列执行汇总操作。

    下面我们可以看到复合组的代码和网格外观:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    string[] cols = new string[2];
    cols[0] = "ShipRegion";
    cols[1] = "ShipName";
    helper.RegisterGroup(cols, true, true);
    helper.ApplyGroupSort();
    }

    enter image description here

    我们可以向组中添加摘要。这次我们将定义一个平均操作并添加一个标签来指示该操作:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    string[] cols = new string[2];
    cols[0] = "ShipRegion";
    cols[1] = "ShipName";
    helper.RegisterGroup(cols, true, true);
    helper.RegisterSummary("ItemTotal", SummaryOperation.Avg, "ShipRegion+ShipName");
    helper.GroupSummary += new GroupEvent(helper_GroupSummary);
    helper.ApplyGroupSort();
    }

    private void helper_GroupSummary(string groupName, object[] values, GridViewRow row)
    {
    row.Cells[0].HorizontalAlign = HorizontalAlign.Right;
    row.Cells[0].Text = "Average";
    }

    enter image description here

    最后一个示例将创建一个抑制组。值得一提的是,如果定义了抑制组,则不能创建其他组。同理,如果已经定义了一个组,我们就不能创建一个抑制组,如果我们尝试它会引发异常。

    下面我们可以看到抑制组的代码和网格外观:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.SetSuppressGroup("ShipName");
    helper.RegisterSummary("Quantity", SummaryOperation.Sum, "ShipName");
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum, "ShipName");
    helper.ApplyGroupSort();
    }

    enter image description here

    对于未定义汇总操作的列,不显示任何值。这是有道理的,因为 GridViewHelper 不知道如何继续将组行中找到的值汇总为唯一值。这提醒了某些已知消息:

    “选择列表中的列 'column_name' 无效,因为它不包含在聚合函数或 GROUP BY 子句中。”

    显示没有汇总操作的列是没有意义的,为了隐藏它们,我们需要调用一个方法:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.SetSuppressGroup(rdBtnLstGroup.SelectedValue);
    helper.RegisterSummary("Quantity", SummaryOperation.Sum, "ShipName");
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum, "ShipName");
    helper.SetInvisibleColumnsWithoutGroupSummary();
    helper.ApplyGroupSort();
    }

    我知道,这是一个很大的名字!生成的网格如下所示:

    enter image description here

    汇总操作

    GridViewHelper 内置了三个汇总操作:sum、average 和 row count。一个非常有用的功能是可以定义自定义汇总操作。为了实现这一点,我们需要为 GridViewHelper 提供两个方法。将为网格(或组)中找到的每一行调用一个方法,并调用另一个方法来检索汇总操作的结果。下面我们有一个自定义汇总操作的示例。半虚拟操作将返回找到的最小值:
    private List<int> mQuantities = new List<int>();

    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterSummary("Quantity", SaveQuantity, GetMinQuantity);
    }

    private void SaveQuantity(string column, string group, object value)
    {
    mQuantities.Add(Convert.ToInt32(value));
    }

    private object GetMinQuantity(string column, string group)
    {
    int[] qArray = new int[mQuantities.Count];
    mQuantities.CopyTo(qArray);
    Array.Sort(qArray);
    return qArray[0];
    }

    在上面的代码中,我们可以看到所需的方法签名。两者都接收汇总的组名和列名。如果摘要与组无关,则组参数将为空。为网格中找到的每一行调用的方法也接收当前行中列的值。

    生成的网格如下所示:

    enter image description here

    限制

    在一个示例中,我们说我们可以模拟分层分组。尽管网格似乎呈现分层分组,但实际实现并不是分层的。没有组或子组。只有按顺序注册的组。如果我们需要为内部组创建摘要,这就会成为一个问题。下面我们可以看到在这种情况下会发生什么:
    protected void Page_Load(object sender, EventArgs e)
    {
    GridViewHelper helper = new GridViewHelper(this.GridView1);
    helper.RegisterGroup("ShipRegion", true, true);
    helper.RegisterGroup("ShipName", true, true);
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum, "ShipName");
    helper.RegisterSummary("ItemTotal", SummaryOperation.Sum);
    helper.GroupSummary += new GroupEvent(helper_Bug);
    helper.ApplyGroupSort();
    }

    private void helper_Bug(string groupName, object[] values, GridViewRow row)
    {
    if (groupName == null) return;

    row.BackColor = Color.Bisque;
    row.Cells[0].HorizontalAlign = HorizontalAlign.Center;
    row.Cells[0].Text = "[ Summary for " + groupName + " " + values[0] + " ]";
    }

    enter image description here

    如我们所见,摘要是在外部组的标题之后创建的。发生这种情况是因为事件序列是:
    Group1_Start
    Group1_End
    Group2_Start
    Group2_End

    对于分层分组,事件序列应该是:
    Group1_Start
    Group2_Start
    Group2_End
    Group1_End

    实现

    GridViewHelper 是作为独立类而不是继承类实现的。这使得可以将 GridViewHelper 与任何 GridView 一起使用,并且不会强制开发人员继承特定的 GridView,这会影响类设计。解决方案中还有另外四个类:GridViewSummary、GridViewGroup、GridViewSummaryList 和 GridViewGroupList。创建“列表”类以允许字符串索引器访问:helper.GeneralSummaries["ItemTotal"].Value。

    创建 GridViewHelper 时,会保存对目标 GridView 的引用,并将 RowDataBound 事件绑定(bind)到执行繁重工作的方法:
    public GridViewHelper(GridView grd, bool useFooterForGeneralSummaries, SortDirection groupSortDirection)
    {
    this.mGrid = grd;
    this.useFooter = useFooterForGeneralSummaries;
    this.groupSortDir = groupSortDirection;
    this.mGeneralSummaries = new GridViewSummaryList();
    this.mGroups = new GridViewGroupList();
    this.mGrid.RowDataBound += new GridViewRowEventHandler(RowDataBoundHandler);
    }

    GridViewHelper 内部使用的一些方法被定义为公共(public)方法,因为它们提供了一些自定义可能需要的有用功能。还有一些其他选项未在示例中显示,但可以使用 Visual Studio 智能感知轻松验证。

    已知问题

    性能可能会因值类型的过多装箱和拆箱而受到影响。为了解决这个问题,我们可以使用泛型实现内置的汇总操作,但这并不像我们希望的那样容易,正如在使用泛型进行计算中可以看到的那样。另一种可能性:运算符重载泛型。在现实生活中,这不会影响应用程序,除非有一百万行,或者有数千个用户同时分组和汇总数据。

    在线示例将 GridView EnableViewState 保持为 false。这是必需的,因为当 EnableViewState 为 true 时,如果页面处于 PostBack 状态,则 GridView 将从 ViewState 重建,并且不会触发 RowDataBound 事件。我们可以安全地禁用 ASP.Net 2.0 中的 ViewState,因为 ControlState 仍将被保存。

    关于c# - 在 Asp.Net Gridview 中分组数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13134427/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com