C# Asp.NETGridView中的数据分组
我有两个存储过程,它们返回两组相关数据。数据是这样的。 第一个过程返回如下数据C# Asp.NETGridView中的数据分组,c#,asp.net,gridview,C#,Asp.net,Gridview,我有两个存储过程,它们返回两组相关数据。数据是这样的。 第一个过程返回如下数据 ISSUE_ID ISSUETYPE ------------------------------------- 1 ISSUE 1 TYPE 2 ISSUE 2 TYPE 3 ISSUE 3 TYPE 4 ISSUE 4 TYPE 第二个过程根据问题ID返回如下数据 HEADER ID
ISSUE_ID ISSUETYPE
-------------------------------------
1 ISSUE 1 TYPE
2 ISSUE 2 TYPE
3 ISSUE 3 TYPE
4 ISSUE 4 TYPE
第二个过程根据问题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\u 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
提前感谢一百万。。需要一些建议来实现这一点
ASP.Net GridView中的分组示例
首先,我们创建GridViewHelper设置它将在构造函数中操作的网格。然后注册摘要,指定列名和要执行的摘要操作。结果如下:
在此示例中,添加了一个新行以显示摘要。另一个选项是使用页脚行显示摘要,而不是创建新的摘要。向网格中添加新行时,仅创建显示汇总列所需的单元格。使用页脚创建所有单元格。对于组摘要,生成所有单元格或仅生成所需单元格是组属性
现在我们将创建一个组。代码如下所示:
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已隐藏:
让我们做一些更有趣的事情,让我们为创建的组添加一个摘要。我们只需再增加一行即可向小组注册摘要:
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”
我们可以在下面的网格中看到分组和组摘要:
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();
}
可以在网格中创建多个组,模拟分层分组,如下所示:
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();
}
结果:
当存在多个组时,可视化会受到影响。GridViewHelper具有允许轻松实现视觉或功能调整的事件。活动清单如下:
- GroupStart:在新组启动时发生,这意味着在组列中找到新值时
- GroupEnd:发生在组的最后一行
- GroupHeader:为组添加自动标题行时发生。如果组不是自动的,则不会触发该事件
- GroupSummary:为组生成摘要行时发生。如果该组不是自动组,则不会触发该事件,但如果该组是抑制组,则会触发该事件(稍后将看到)
- 一般摘要:在计算一般摘要之后发生。如果摘要是自动的,则事件发生在添加摘要行和将摘要值放入该行之后
- 页脚数据绑定:在页脚数据绑定中发生
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 = " " + row.Cells[0].Text;
}
else if (groupName == "ShipName")
{
row.BackColor = Color.FromArgb(236, 236, 236);
row.Cells[0].Text = " " + row.Cells[0].Text;
}
}
化妆品后的网格:
更多分组选项
还有两个有趣的例子。第一个是复合群。第二个定义了一个suppress组,其行为与SQLGROUPBY子句相同。将抑制重复值,并对其他列执行摘要操作
下面我们可以看到复合组的代码和网格外观:
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();
}
我们可以在小组中添加摘要。这次我们将定义一个平均操作,并添加一个标签来指示该操作:
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";
}
最后一个示例将创建一个抑制组。必须指出的是,如果定义了抑制组,则不能创建其他组。同样,如果已经定义了一个组,我们不能创建一个抑制组,如果我们尝试它,将引发一个异常
下面我们可以看到抑制组的代码和网格外观:
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();
}
对于未定义摘要操作的列,不显示任何值。这很有意义,因为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();
}
我知道,这是个大名字!生成的网格如下所示:
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();
}
摘要操作
GridViewHelper有三个内置的摘要操作:求和、平均和行计数。一个非常有用的功能是可以定义自定义摘要操作。为了实现这一点,我们需要为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];
}
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] + " ]";
}
Group1_Start
Group1_End
Group2_Start
Group2_End
Group1_Start
Group2_Start
Group2_End
Group1_End
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);
}
readonly Dictionary<Control, string> _groupNames = new Dictionary<Control, string>();
private Group _lastGroup;
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var obj = (Obj)e.Row.DataItem;
if (obj.Group != _lastGroup)
{
e.Row.SetRenderMethodDelegate(RenderGridViewRowWithHeader);
_lastGroup = obj.Group;
// Cache group description for this row, note that you might
// like to implement this differently if you have your data normalized.
_groupNames[e.Row] = obj.Group.Description; }
}
}
}
private void RenderGridViewRowWithHeader(HtmlTextWriter output, Control container)
{
// Render group header
var row = new TableRow { CssClass = "groupingCssClass" };
row.Cells.Add(new TableCell());
row.Cells.Add(new TableCell
{
ColumnSpan = ((GridViewRow)container).Cells.Count - 1,
Text = _groupNames[container]
});
row.RenderControl(output);
// Render row
container.SetRenderMethodDelegate(null); // avoid recursive call
container.RenderControl(output);
}