好几天没更新博客了,这几天都忙着修改代码。我老大(豪客)给我的任务还是比较重的,o(∩_∩)o...哈哈,今天就跟大家聊一下这几天的收获。希望能跟大家一起分享。
首先以前页面的截图如下:
更新后的截图如下:
更新2个”查询“限制条件,以便能查询下面表中更详细的内容,还有一个“统计”按钮,统计当前条件下表中的“项目状态”为“结束”、“进行中”、“被关闭”、“停止”的项目分别有多少个。
我用“项目状态”的下拉控件举例,“完成日期”、“项目类型”和它实现差不多。
1.页面代码:
<
asp:DropDownList
ID
="DropDownList3"
runat
="server" DataSource="<%# ProjectZt %
>" DataTextField="codeText" DataValueField="codeValue" OnDataBound="DropDownList3_DataBound">
</asp:DropDownList>
</asp:DropDownList>
说明:在页面的Table中增加一个dropdownlist控件。当中的参数在大家耐心慢慢看下去就知道是什么意思了。
2.后台代码片段:
public DataTable ProjectZt
{
get
{
return ( new CommonBLL()).GetZt_new( "projectStatusType");
}
}
{
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;
}
{
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;
}
{
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 + "')"就是调用数据库的方法,当然也可以写到数据库存储过程中,直接调用存储过程访问数据库。
+ "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个条件绑定数据
{
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
{
Session[ "PrjTypeTime"] = null;
Session[ "PrjTypeZt"] = null;
}
else
{
//页面继承了一个基类PageBase,当中已经封装好了方法和类。
prjType = SessionGetInt( "PrjType");
prjTypeTime = SessionGetInt( "PrjTypeTime");
prjTypeZt = SessionGetInt( "PrjTypeZt");
}
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);
}
{
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 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;
}
{
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);
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));
}
}
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() + "个";
}
}
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
,如需转载请自行联系原作者