65.9K
CodeProject 正在变化。 阅读更多。
Home

已排序 DataGrid 中的条形图柱

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.14/5 (3投票s)

2006年6月7日

CPOL

4分钟阅读

viewsIcon

49485

在C#中创建一个排序后的DataGrid中的条形图列。

Sample Image - example.gif

引言

这是我第一次尝试为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项(或行)为ItemAlternatingItem类型时发生;之后,我们不想为页眉或分页器部分创建图表。

就是这样,非常快,非常粗略,但它确实有效。

正如我一开始所说的,相当简单;如果我的描述使事情复杂化,请告诉我。其他示例可在www.chemlock.co.uk上找到。

© . All rights reserved.