已排序 DataGrid 中的条形图柱
在C#中创建一个排序后的DataGrid中的条形图列。
引言
这是我第一次尝试为CodeProject撰写文章。我使用了足够多的其他人的文章,所以我想我最好也回馈一些内容。过去大约6年时间里,我一直从事网站开发工作,从PHP到C#.NET都涉及到。有关其他示例,请访问http://www.chemlock.co.uk/的“开发”部分。下面的项目是使用C#编写的ASP.NET项目。需要在DataGrid
中为每一行显示一个简单的条形图,以快速说明数量。这非常简单,所以我将其设置为初学者级别。如有任何问题,请给我发邮件。
DataGrid中的图表显示
今天早上,我有幸将一位顾问的代码重写成可运行且易于开发的内容。出于某种奇怪的原因,这家伙用经典ASP编写了他所有的代码,将数据库连接字符串硬编码到文件中,并动态创建所有SQL语句。这很慢。不仅因为它使用了经典ASP,而且SQL字符串不断变化,服务器无法缓存查询,而且因为它编写得很糟糕。一个页面在HTTP请求流中传递两个变量,然后使用这些变量从数据库中提取相同的两个值。毫无意义且耗时。无论如何,结果被扔进表格中,所有表格中的一列都是一个图表,用于显示每周预订到项目的时间量。这是在最多60小时的基础上(不知道哪个傻瓜在做这些小时)。我的朋友,那位高薪顾问,通过在一个表格单元格内创建一个表格来实现这一点,该表格的宽度等于小时数。这意味着如果您为一个项目预订了34小时,则图表将长34像素。
我被要求修复一些SQL语句,因为对于其中一个报表来说,结果不太相关,但我认为将所有内容迁移到.NET和存储过程将是一个相当快速简单的任务。因此,这是我关于在DataGrid
中创建图表列的快速简易指南。它非常简单(实际上是C#),当然不是火箭科学。
首先,创建一个干净整洁的Web窗体。这是代码隐藏部分
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
if(Request["EmployeeNo"] != null)
{
Db db = new Db();
ArrayList parameters = new ArrayList();
parameters.Add(new DbParameter("@EmployeeNo",DbType.String,
10,"EmployeeNo",Request["EmployeeNo"].ToString()));
Session["dataset"] = db.GetDataSet("GetEmployeeBookings",parameters);
Session["SortOn"] = "EndDate";
Session["SortDirection"] = " DESC";
}
}
BindGrid();
}
请注意,我使用了一个名为DB
的类来访问我的数据库并创建一个DataSet
。在这里可以使用任何你喜欢的;要点是最终得到你的结果的DataSet
。我还为我的DataGrid
设置了初始排序参数以及它们将被排序的初始方向。每次回发都会使用数据绑定网格,但只有初始传递才会从数据库获取数据。显然,如果此数据可能会因任何页面操作而更改,我会将此数据库调用移至单独的方法,但由于它是一个静态报表,而且我时间紧迫,所以我保留了最初的写法。
private void BindGrid()
{
if (Session["dataset"] != null)
{
DataTable dt = ((DataSet)Session["dataset"]).Tables[0];
DataView dv = dt.DefaultView;
dv.Sort = Session["SortOn"].ToString() + Session["SortDirection"].ToString();
this.DataGrid1.DataSource = dv;
this.DataGrid1.DataBind();
}
这是BindGrid
方法。它首先检查会话变量中是否存在某些内容。如果存在,它会提取它,创建一个正确排序的DataView
,然后将其绑定到我们的DataGrid
控件。请注意,我对DataGrid
的命名有多么随意。记住,这是快速简易的。
private void DataGrid1_SortCommand(object source,
System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
Session["SortOn"] = e.SortExpression.ToString();
if (Session["SortDirection"] == null ||
Session["SortDirection"].ToString() == " ASC")
{
Session["SortDirection"] = " DESC";
}
else
{
Session["SortDirection"] = " ASC";
}
this.DataGrid1.CurrentPageIndex = 0;
BindGrid();
}
这是一个标准的排序事件方法。基本上,如果您选择一个已经选择的列标题,它将更改该列的方向。任何其他列,网格都会根据新的列标题进行排序。
private void DataGrid1_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
decimal hours = decimal.Parse(e.Item.Cells[3].Text);
decimal percentage = (100m / 60m) * hours;
e.Item.Cells[4].Text = "<div style= "WIDTH: 100%"><div " +
"style= 'BACKGROUND-COLOR:RED;HEIGHT: 10px;WIDTH:"+
percentage + "%'></div></div> ";}
}
这是构建图表的地方。在我持续努力摆脱不应使用表格的地方使用表格的过程中,我采用了“DIV”方法。首先,我创建一个填充整个单元格的Div
。然后,在其中,我创建一个占父Div
一定百分比的Div
。请注意,如果没有高度命令,图表将不会在Firefox中显示。因此,我有我的60小时,然后计算出子Div
宽度的百分比。代码设置为在DataGrid
的每一行绑定数据时应用此代码。每次都会从数据库中的另一列(在本例中为第3列)计算小时数并将其解析为十进制数。生成的HTML代码被注入到第4个单元格中。所有这些都设置为仅在DataGrid
项(或行)为Item
或AlternatingItem
类型时发生;之后,我们不想为页眉或分页器部分创建图表。
就是这样,非常快,非常粗略,但它确实有效。
正如我一开始所说的,相当简单;如果我的描述使事情复杂化,请告诉我。其他示例可在www.chemlock.co.uk上找到。