用“已知”的办法解决“未知”的办法---.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.我一开始想让页面即使允许分页也能把全部的数据都统计出来,我试了很多方法,还是没试出来,希望能有高人指点,现在把全部数据堆到一个页面点“统计”我感觉会有一点慢。
 
        我知道我自己啰里八嗦的写那么多很少会有耐心能看完,但是我觉得我该完这个东西我收获很大,所以我希望跟大家分享,我还比较菜,希望大家多多指点。
        信心和努力伴随着我们,让我们一起眺望远方,即使远方很远~~





     本文转自L.net 51CTO博客,原文链接:http://blog.51cto.com/mixangel/55806 ,如需转载请自行联系原作者



相关文章
|
1月前
|
C#
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
|
存储 C# 数据库
.NET开源的在Windows上统计软件使用时长和网站浏览时长工具 - Tai
.NET开源的在Windows上统计软件使用时长和网站浏览时长工具 - Tai
110 0
|
4月前
|
开发框架 JavaScript 前端开发
震撼!破解 ASP.NET 服务器控件 Button 执行顺序之谜,颠覆你的开发认知!
【8月更文挑战第16天】在ASP.NET开发中,通过Button控件实现先执行JavaScript再触后台处理的需求十分常见。例如,在用户点击按钮前需前端验证或提示,确保操作无误后再传递数据至后台深度处理。此过程可通过设置Button的`OnClientClick`属性调用自定义JavaScript函数完成验证;若验证通过,则继续触发后台事件。此外,结合jQuery也能达到相同效果,利用`__doPostBack`手动触发服务器端事件。这种方式增强了应用的交互性和用户体验。
52 8
|
2月前
|
开发者 Windows
.NET 开源扁平化、美观的 C/S 控件库
【10月更文挑战第23天】介绍了三款适用于 .NET 平台的开源扁平化、美观的 C/S 控件库:MaterialSkin 采用 Google Material Design 风格,适合现代感界面;Krypton Toolkit 提供丰富控件,界面易于定制;Fluent Ribbon Control Suite 模仿 Office 界面,适合复杂功能应用。每款控件库均附有示例代码及 GitHub 链接。
106 0
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
2月前
|
C# Android开发 iOS开发
一组.NET MAUI绘制的开源控件 - AlohaKit
一组.NET MAUI绘制的开源控件 - AlohaKit
|
3月前
|
开发框架 JavaScript 前端开发
|
7月前
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
97 0
|
7月前
|
SQL 开发框架 前端开发
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
88 0