用“已知”的办法解决“未知”的办法---.NET连动控件和统计数量

        好几天没更新博客了,这几天都忙着修改代码。我老大(豪客)给我的任务还是比较重的,o(∩_∩)o...哈哈,今天就跟大家聊一下这几天的收获。希望能跟大家一起分享。
首先以前页面的截图如下:
更新后的截图如下:
更新2个”查询“限制条件,以便能查询下面表中更详细的内容,还有一个“统计”按钮,统计当前条件下表中的“项目状态”为“结束”、“进行中”、“被关闭”、“停止”的项目分别有多少个。
 
        我用“项目状态”的下拉控件举例,“完成日期”、“项目类型”和它实现差不多。
1.页面代码:
< asp:DropDownList ID ="DropDownList3" runat ="server" DataSource="<%# ProjectZt % >"   DataTextField="codeText" DataValueField="codeValue" OnDataBound="DropDownList3_DataBound">
                                 </asp:DropDownList>
说明:在页面的Table中增加一个dropdownlist控件。当中的参数在大家耐心慢慢看下去就知道是什么意思了。
 
2.后台代码片段:
public DataTable ProjectZt
        {
            get
            {
                 return ( new CommonBLL()).GetZt_new( "projectStatusType");
            }
        }
说明:页面中的DataSource绑定的数据在后台中实现。并且调用业务逻辑层(BLL)的类CommonBLL。
 
3.业务逻辑层中CommonBLL的代码片段:
public DataTable GetZt_new( string type)
        {
            DataTable table;

            table = CommonDA.GetCodeList3(type).Tables[0];

             return table;
        }
说明:程序继续调用数据逻辑层(DAL),并且返回table。
 
4.数据访问层中CommonDA的代码片段:
public static DataSet GetCodeList3( string typeName)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = CONN;

             string sql = "select a.codeValue, a.codeText, a.subId from bsCodeList a "
                + "INNER JOIN bsCodeType b ON a.codeType = b.id where (b.name = '" + typeName + "')";
            SqlCommand objcommand = new SqlCommand();
            objcommand.Connection = conn;
            objcommand.CommandType = CommandType.Text;
            objcommand.CommandText = sql;
            SqlDataAdapter commandAdp = new SqlDataAdapter();
            commandAdp.SelectCommand = objcommand;
            DataSet data = new DataSet();
            commandAdp.Fill(data, "CodeList3");
            conn.Close();
             return data;
        }
说明:这一层开始调用数据库中的表,并且获取数据。没什么太难的,都是固定语句,只是一步一步的调用,当然直接从后台文件里直接调用这一层也可以,或者直接写入后台都可以。这样写的代码清晰性会好一些。
 
5.所设计到的数据库:(两个表)
 
说明:数据访问层中的string sql = "select a.codeValue, a.codeText, a.subId from bsCodeList a "
                + "INNER JOIN bsCodeType b ON a.codeType = b.id where (b.name = '" + typeName + "')"就是调用数据库的方法,当然也可以写到数据库存储过程中,直接调用存储过程访问数据库。
        大家可能已经都注意到了。数据库中有两个页面中出现的参数codeValue和codeText,让我们“return 1.页面代码”,这两个就绑定在控件中DataValueField和DataTextField中,DataTextField就是我们看到绑定的内容。
        到这里控件的内容我们绑定好了,下面我们就要实现当我们选中当中的内容时,点“查询”或者“统计”按钮,下面显示的表(DataGrid控件)重新绑定我们规定条件的数据。
 
6.让我们“return 2.后台代码”:
        实现完控件的绑定,下面就是Page_Load中的代码,这里面的代码意思是,当页面加载的时候所实现的功能,即用户向服务端每提交一次请求就加载当中的命令。当中有个很重要的语句If(!IsPostBack),意思是当页面是用户第一次加载的时候要执行的命令。这里有熟悉的朋友也有不熟悉的朋友,所以我尽量用简短的话来描述一下,如果还不是太清楚就试一试有无这个命令If(!IsPostBack)时的效果。
        代码片段:
if (!IsPostBack)
            {

                CheckBox1.Checked = false;
                 //“不分页”控件是实现下面显示表(DataGrid)是否分页要求的。在页面第一次加载默认是分页的


                 if (Session[ "PrjType"] != null && Session[ "PrjTypeTime"] != null && Session[ "ProjectStatus"] != null)
                {
                    prjType = SessionGetInt( "PrjType");
                    dropProjectType.DataBind();
                    dropProjectType.SelectedValue = Session[ "PrjType"].ToString();

                    prjTypeTime = SessionGetInt( "PrjTypeTime");
                    DropDownList1.DataBind();
                    DropDownList1.SelectedValue = Session[ "PrjTypeTime"].ToString();

                    prjTypeZt = SessionGetInt( "PrjTypeZt");
                    DropDownList3.DataBind();
                    DropDownList3.SelectedValue = Session[ "PrjTypeZt"].ToString();
                }
                 else
                {
                    prjType = 0;
                    dropProjectType.DataBind();
                    dropProjectType.SelectedValue = "0";

                    prjTypeTime = 0;
                    DropDownList1.DataBind();
                    DropDownList1.SelectedValue = "0";

                    prjTypeZt = 3;
                    DropDownList3.DataBind();
                    DropDownList3.SelectedValue = "3";

                }
                BindProjects(prjType, prjTypeTime, prjTypeZt); //根据目前3个条件绑定数据
                  Session[ "PrjType"] = null;
                Session[ "PrjTypeTime"] = null;
                Session[ "PrjTypeZt"] = null;
            }
             else
            {
               //页面继承了一个基类PageBase,当中已经封装好了方法和类。
                prjType = SessionGetInt( "PrjType");
                prjTypeTime = SessionGetInt( "PrjTypeTime");
                prjTypeZt = SessionGetInt( "PrjTypeZt");
            }
说明:页面绑定3个限制条件控件的初始值,根据目前的条件进行加载。其他的参数设置页面的默认属性,以便当用户执行完一个过程后回到页面初始。
        这里有一个小技巧,就是我们在3个下拉控件中已经绑定好了内容,但是我定义了,一个“所有类型”,也就是当某个控件的条件为“所有类型”的时候,它就不具有任何的限制了。
        代码片段:
protected void DropDownList3_DataBound( object sender, EventArgs e)
        {
            ListItem item = new ListItem( "所有类型", "3");
            DropDownList drop = (DropDownList)sender;
            drop.Items.Add(item);
        }
说明:在DataBound事件中新添加一个选项“所有类型”。大家“return 5.所设计到的数据库”,看codeValue一列数据,代码中的“3”是为了区别于其他的选项,其他两个下拉控件,因为是从“1”开始写入到数据库的,所以就用“0”表示新增了。
 
7.绑定
private void BindProjects( int type, int typetime, int typezt)
        {
            ProjectsCollection projectList = Project.GetProjects(_user.UserID, _user.Role, Convert.ToInt32(dropProjectType.SelectedValue), Convert.ToInt32(DropDownList1.SelectedValue), Convert.ToInt32(DropDownList3.SelectedValue));

            SortGridData(projectList, SortField, SortAscending);
ProjectsGrid.DataSource = projectList;
             try
            {
                ProjectsGrid.DataBind();
            }
             catch
            {
                ProjectsGrid.CurrentPageIndex = (ProjectsGrid.CurrentPageIndex - 1 > 0 ? ProjectsGrid.CurrentPageIndex - 1 : 0);
                ProjectsGrid.DataBind();
            )        
        }
说明:这一段代码用到了两个业务逻辑层的类ProjectsCollection和Project。userid和role是控制权限用的,不用管它。在绑定显示表的时候(ProjectsGrid.DataBind()),一定要做溢出判断,否则会出现BUG。
       ProjectsCollection.cs代码提供一个封装数据的功能。那些数据就是Project.cs所用到的。
        Project.cs代码片段:
public static ProjectsCollection GetProjects( int userID, string role, int type, int typetime, int typezt)
        {
            DataSet ds = SqlHelper.ExecuteDataset(
                ConfigurationManager.AppSettings[ "ConnectionString"],
                 "PM_ListProjectsTime", userID, Convert.ToInt32(role));
ProjectsCollection projects = new ProjectsCollection();

             foreach (DataRow r in ds.Tables[0].Rows)
            {
                Project prj = new Project();

                prj.ProjectType = Convert.ToInt32(r[ "ProjectType"]);
prj.ProjectTypeTime = Convert.ToInt32(r[ "ProjectTypeTime"]);

                    prj.ProjectStatus = Convert.ToInt32(r[ "ProjectStatus"]);

                     if ((type == 0 || prj.ProjectType == type) && (typetime == 0 || prj.ProjectTypeTime == typetime) && (typezt == 3 || prj.ProjectStatus == typezt))
                        {
                            prj.ProjectID = Convert.ToInt32(r[ "ProjectID"]);                        prj.Name = r[ "ProjectName"].ToString();
                            prj.Description = r[ "Description"].ToString();
                            prj.ProjectCode = r[ "ProjectCode"].ToString();
                            prj.ManagerUserID = Convert.ToInt32(r[ "ManagerUserID"]);
                            prj.ManagerUserName = Convert.ToString(r[ "Username"]);
                             prj.EstCompletionDate = Convert.ToDateTime(r[ "EstCompletionDate"]);
                             prj.EstDuration = Convert.ToDecimal(r[ "EstDuration"]);
                         //prj.ProjectStatus = Convert.ToInt32(r["ProjectStatus"]);
                             projects.Add(prj);
                         }
              
            }

             return projects;
        }
说明:当中设计到的一个数据库存储过程 PM_ListProjectsTime
          PM_ListProjectsTime 代码入下:

CREATE   PROCEDURE PM_ListProjectsTime
(
    @UserID int,
    @RoleID int
)
AS

IF @RoleID = 1 /*全部*/
BEGIN
     SELECT ProjectID,  
   Name as ProjectName,  
  Description,  
  ManagerUserID,  
  EmpName as UserName,
  EstCompletionDate,  
  EstDuration,
  ProjectCode,
  ProjectStatus,
  ProjectType,
  ProjectTypeTime
     FROM  
  PM_Projects
     INNER JOIN
  mrBaseInf
     ON  
  ManagerUserID = EmpID   order by ProjectName
END

ELSE IF @RoleID = 2   /*自己管的项目*/
BEGIN
     SELECT ProjectID,  
   Name as ProjectName,  
  Description,  
  ManagerUserID,  
  EmpName as UserName,
  EstCompletionDate,  
  EstDuration,
  ProjectCode,
  ProjectType,
  ProjectTypeTime,
  ProjectStatus
     FROM  
  PM_Projects
     INNER JOIN
  mrBaseInf
     ON  
  ManagerUserID = EmpID
     WHERE ManagerUserID = @UserID   order by ProjectName
END
GO
说明:根据条件,获得参数,然后传到后台,再根据页面中绑定的Value值来绑定具体的内容。
到现在也实现好根据条件绑定下面表的内容了。
8.两个控件“查询”和“统计”功能的实现。
“查询”功能代码:
protected void Button1_Click( object sender, EventArgs e)
{
                  //因为下面表(ProjectsGrid)是分页的,所以我定义每次查询都看到的是第一页。也就是简单的复位功能
                ProjectsGrid.CurrentPageIndex = 0;
                Session[ "PrjType"] = Convert.ToInt32(dropProjectType.SelectedValue);

                Session[ "PrjTypeTime"] = Convert.ToInt32(DropDownList1.SelectedValue);

                Session[ "PrjTypeZt"] = Convert.ToInt32(DropDownList3.SelectedValue);
                  //我在这里也做了异常处理,后面我会做解释。这里大家可以直接理解为:BindProjects(Convert.ToInt32(dropProjectType.SelectedValue), Convert.ToInt32(DropDownList1.SelectedValue), Convert.ToInt32(DropDownList3.SelectedValue));
                 try
                {
                    BindProjects(Convert.ToInt32(dropProjectType.SelectedValue), Convert.ToInt32(DropDownList1.SelectedValue), Convert.ToInt32(DropDownList3.SelectedValue));
                                     }
                 catch
                {
                    ProjectsGrid.CurrentPageIndex = (ProjectsGrid.CurrentPageIndex - 1 > 0 ? ProjectsGrid.CurrentPageIndex - 1 : 0);
                    BindProjects(Convert.ToInt32(dropProjectType.SelectedValue), Convert.ToInt32(DropDownList1.SelectedValue), Convert.ToInt32(DropDownList3.SelectedValue));
                                    }
            }
“统计”按钮也是我越到的一个麻烦,因为我要统计当前表中数据“项目状态”的情况,时间有点紧,我测试了很多办法都没有成功。
代码片段:
protected void ProjectsGrid_ItemDataBound(object sender, DataGridItemEventArgs e)
        {
  if (e.Item.ItemType == ListItemType.Item ||
                    e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Label lbl = (Label)e.Item.Cells[3].Controls[1];
                 int status = Int32.Parse(lbl.Text);
                 switch (status)
                {
                     case 0:
                        lbl.Text = "结束";
                        lbl.BackColor = System.Drawing.Color.Gray;
                  
                         break;
                     case 1:
                        lbl.Text = "进行中";

                         break;
                     case -1:
                        lbl.Text = "被关闭";
                        lbl.BackColor = System.Drawing.Color.Red;

                         break;
                     case -2:
                        lbl.Text = "停止";
                        lbl.BackColor = System.Drawing.Color.Red;

                         break;

                }
                
                 if (lbl.Text == "结束")
                {

                    m6 = m6 + 1;
                    Label7.Text = "共" + m6.ToString() + "个";

                }
                 if (lbl.Text == "进行中")
                {
                    m7 = m7 + 1;
                    Label8.Text = "共" + m7.ToString() + "个";

                }
                 if (lbl.Text == "被关闭")
                {
                    m8 = m8 + 1;
                    Label9.Text = "共" + m8.ToString() + "个";

                }
                 if (lbl.Text == "停止")
                {
                    m10 = m10 + 1;
                    Label10.Text = "共" + m10.ToString() + "个";

                }
            }
    }
说明:这个方法是表中的项被绑定时候激发,表中在“项目状态”那一列绑定了一个Label控件,用来显示文字。所以在switch中根据获取来的Value值来判断显示的文字和背景颜色,后面我加的这段代码是显示 当前页面的各个状态的数量,注意其实表是默认分页的,所以我统计的只能是当前一个页面的数据。
        我们“return “统计”按钮”,我用了一个已知的办法解决这个未知的办法,就是当我们点统计的时候,下面表(ProjectGrid)的ProjectsGrid.AllowPaging = false,意思是不允许分页,那么我就可以统计出来了,并且把右上角的“不分页”勾上,当我们再点“查询”和“不分页”的时候,页面就不会再显示“项目状态”那一行的数量了,因为如果不分页我感觉会数据量比较大,页面缓冲比较慢,如果不点“统计”功能,就不要显示统计功能了。当然“统计”功能也要绑定数据,就是也同时拥有“查询”功能,只是不分页显示。
 
总结:我想大家如果看完这篇文章肯定玉石俱焚了,如果能看一半我已经很满足了。在当中我遇到两个问题:
1.溢出问题,我调试了好长时间,才不会出现漏洞。一开始在点“查询”的时候有时就出现BUG,页面无相应,我加上判断语句后已经好了,但是新问题又出现了,因为页面是允许分页的,我点“2”或者其他页面后,然后再根据新条件查询又会有漏洞,最后在DataGrid分页时间中有这两句:ProjectsGrid.CurrentPageIndex = e.NewPageIndex;Session["PM_ListIndex"] = e.NewPageIndex;我把Session["PM_ListIndex"] = e.NewPageIndex;去掉就不会再有BUG了,我也不知道原因,希望高人能指点:-)
2.我一开始想让页面即使允许分页也能把全部的数据都统计出来,我试了很多方法,还是没试出来,希望能有高人指点,现在把全部数据堆到一个页面点“统计”我感觉会有一点慢。
 
        我知道我自己��里八嗦的写那么多很少会有耐心能看完,但是我觉得我该完这个东西我收获很大,所以我希望跟大家分享,我还比较菜,希望大家多多指点。
        信心和努力伴随着我们,让我们一起眺望远方,即使远方很远~~

你可能感兴趣的:(.net,问题,统计,控件,休闲)