请幸运飞艇高手计划解答后一600注计划如何总结啊?

求高手解答600注做号思路???_百度知道
求高手解答600注做号思路???
我和他他是一次面试中认识的,去年11月份认识的,他一直会时不时联系我,约我吃饭或者散步,那时我还谈了个男盆友,后来分手了,很难过,也跟他聊了些,他让我不要相信男人说的要看他怎么做的,要我今后谈恋爱用心享受被追求的过程,不要太早让男人得到,像朋...
我有更好的答案
我多年的彩经验总结投资彩看似运气成分比较大其实里面技术站了很大比例这说明是有技巧和讲究技术的很多心得都是彩民的心血,我认识一个人t a 的 筘 (5722131)但是技巧是经过不断实践才可以运用的A. x1&x2 B. x1&x2 C. x1=x2 D.无法确定解:根据题意,知k=3&0,且y1&y2。根据一次函数的性质“当k&0时,y随x的增大而增大”,得x1&x2。故选A。三、判断函数图象的位置例3. 一次函数y=kx+b满足kb&0,且y随x的增大而减小,则此函数的图象不经过( )A. 第一象限 B. 第二象限C. 第三象限 D. 第四象限解:由kb&0,知k、b同号。因为y随x的增大而减小,所以k&0。所以b&0。故一次函数y=kx+b的图象经过第二、三、四象限,不经过第一象限。故选A .
1条折叠回答
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。项目总结 - 御天六龙 - 博客园
这几天做完了一个中型的项目,学到了许多的东西。在做项目的时候遇到问题时都是上csdn看帖子,我想我遇到的问题别人肯定也会碰到,应该说大部分的问题都可以在csdn上找到答案。所以我在csdn学到了很多的知识,谢谢大家!做项目时想,等我做完项目时就总结一些经验,让后来者学习和借鉴或说不再重复我犯的错误,所以就写了这一篇文章,希望对大家有用!最大的感触就是,csdn上经常有人问,为什么我的dropdownLsit或checkboxlist或其它什么控件不能取到修改后的值,或是不能响应用户的修改(通俗一点的说是老是显示那一个值,不会改变)。其实这个问题最根本的原因是没有完全理解asp.net中页面的执行(处理)过程,今天我们就这个问题说说。参考msdn中的"web&窗体页处理”(ms-help://MS.VSCC/MS.MSDNVS.2052/Vbcon/html/vbconWebFormsPageProcessingStages.htm),我们先理解一个概念---往返行程:浏览器向用户显示一个窗体,用户与该窗体进行交互,这导致该窗体回发到服务器。但是,因为与服务器组件进行交互的所有处理必须在服务器上发生,这意味着对于要求处理的每一操作而言,必须将该窗体发送到服务器、进行处理、然后返回到浏览器。这一事件序列称作“往返行程”。因此我们不难理解,为什么建议多使用html控件(客户端控件),而不是web控件(服务器端控件);为什么web控件不支持onmouseover、onmouseout事件了。因为它们要每触发一次都要在服务器和客户端间往返一次,也就我们所说的会引起"刷屏"&。但我们可以为web控件增加客户端的事件以支持这些操作,因为有时候必须用到。理解了"往返行程"后,我们再来理解一下web页面的另一个特性----无状态性:客户端向服务器发送一个请求(譬如你在IE栏输入网址,回车),服务器接到请求,响应请求(处理事件),服务器完成处理后将生成的web页发送回浏览器,然后就清除该页的信息,释放服务器资源。服务再等待下一次请求,即使下一次是请求同一页,服务器重新开始创建和处理该页。服务器就是这样不停的重复这一过程。服务器不记录页面的状态或信息的特性我们就称之为“无状态性”。也许有朋友会问,我的控件每次刷新时会自动保存状态啊,那是因为asp.net引入了视图状态和状态管理,它会自动保持web控件的状态。关于服务器是怎样保存web控件的状态,我想我以后有能力或有时间的时候再写吧。请接着往下看。理解了这两个基本概念后,我们就来看看asp.net中的服务器处理页面的一个过程,服务器处理页面过程(大概)分以下几个阶段:ASP.NET&页框架初始化(Page_Init()&)à&用户代码初始化(page_load())&à&验证(调用任何验证程序&Web&服务器控件的&Validate&方法来执行该控件的指定验证)&à&事件处理(处理所引发的特定事件)&&à&&清除(page_unload()),每一阶段会触发不同的事件,阶段后面的括号内容就是该阶段触发的事件。由此我们知道服务器每次执行页面代码的过程就是:page_init()&à&page_load()&à&vlidate函数(web控件的验证事件,应具体到实际的应用中)à&引起页面回发的具体事件(例如button&的click事件等)&à&page_unload()。如果不考虑具体的页面执行,我们可以看出,页面每次处理时,都要执行Page_Init、Page_load、page_unload事件。回到我们的主题,如要我们把dropdownlist&或其它的控件的初始化代码都放在某些方面page_load事件里面执行,那么意思就是每次页面刷新或被请求时控件都被重新初始化了。因此就有了控件的值永远都不会变的问题了。所以我们应该把初始化控件的代码放在:if&(!Page.IsPostBack){&//放在这里}。说到这里,我想问题就说清楚了,不知你明白了吗?谢谢大家捧场!!欢迎大家讨论和指正。如果大家想了解视图状态和状态管理,请参见:ms-help://MS.VSCC/MS.MSDNVS.2052/Vbcon/html/vbconwebformstate.htm及下面这篇文章:如果你想更深的了解页面或控件的执行过程,请参见:ms-help://MS.VSCC/MS.MSDNVS.2052/cpguide/html/cpconcontrolexecutionlifecycle.htm&
在项目实际应用中,常用datagrid控件,datagrid控件非常好用,今天我们来讲讲datagrid的基本的原理和概念性的东西,然后在续篇中我们会介绍datagrid的一些实用技巧。&&&首先我们来看一下datagrid的组成,我们可以把datagrid理解成是html里面的一个table,table是由行(tr)和列(td)组成,而datagrid的行其实是datagriditem对象,而列就是datagridcolumn&对象。在datagrid对象的属性集了我们可以看到items和columns&属性,它们分别就是datagrid的行集和列集,也就是datagriditem对象集合及datagridcolumn&对象集合。通过查看asp.net生成的html页的源代码,我们也可以发现,datagrid的表现形式也就是table。&&&&我们也可以把datagrid理解成数据库里面的表,也是由行和列组成。就像我们建数据库表一样,我们首先要构造表的列,在创建一个datagrid对象时,我们也是要先创建datagrid的列。Datagrid的列有以下几种类型:BoundColumn(绑定列)、ButtonColumn(按钮列)、EditCommandColumn(编辑命令列)、HyperLinkColumn(超链接列)、TemplateColumn(模板列)。每种类型列实现的功能不一样,这里不一一细说了,大家可以在msdn查:ms-help://MS.VSCC/MS.MSDNVS.2052/cpref/html/frlrfSystemWebUIWebControlsDataGridClassTopic.htm。&&&&说完了datagridcolumn对象,我们再来看看datagriditem对象的类型,datagriditem有以下七种类型(它们组成ListItemType枚举类型的七种类型,不包含Separator,Separator一般用于datalist和repeater控件分隔行,不能绑定数据):Header(标题行)&/&Item&(正常数据绑定行)&/&AlternatingItem(数据绑定分隔行)&/&footer(脚注行)&/&edititem(编辑行)&/&Pager(分页导航行)&/&SelectedItem(选中行),通过datagriditem的itemtype属性,我们可以知道某个datagriditem对象是哪一种类型,从而进行不同的处理。这在我们定制多表头及分页导航栏等一些情况下非常有用,后续篇我们会讲到这些应用。&&&&然后我们看看datagrid支持的一些常用的事件,它们在什么条件下触发?它们执行的顺序是什么?它们会触发时改变了哪些属性和对象?这些问题对编辑人员来说是非常重要的。也是我们用好datagrid&的基础,下面我们分别讲述DataBinding、itemcommand、itemcreated、itemdatabound这几个事件。&&&&因为datagrid是以列的形式来呈现(表现)数据的,一般情况下我们在声明一个datagrid的时候,就指定了datagrid要显示的列,所以datagrid的创建工作就只是创建行的工作了。当我们设置了datagrid的datasource属性,就调用datagrid的databind()方法,把数据源绑定到datagrid上,这时就触发了databinding事件。因为我们使用datagrid主要就是和数据打交道,我们可以把databinding事件看作是创建datagrid&的入口,也就是datagrid的创建工作是由databinding事件开始,它是创建datagrid最先执行的事件。接着,datagrid根据数据源开始创建行的工作。&&&&通过监视,我们发现datagird按如下顺序创建行(假设我们先把datagird&的allowpaging属性设为&true):PageràHeaderàItemà&AlternatingItemàItemà&AlternatingItemà&Itemà……(直至创建完所有内容行)àFooteràPager&;如果我们把datagird&的allowpaging属性设为&,datagird则按如下顺序创建行:&HeaderàItemà&AlternatingItemàItemà&AlternatingItemà&Itemà……(直至创建完所有内容行)àFooter&;如果我们是按下了edit&button(或select&button)&,datagrid首先要取得edititem或selecteditem的itemindex,然后在创建行的过程中,与正在创建行的itemindex属性比较,如果相等,则这一行按照edititemtemplate或selecteditemtemplate规定的模板创建,那么datagrid按如下顺序创建行:HeaderàItemà&AlternatingItemàItemà&AlternatingItemà&Itemà…àedititem(selecteditem)à…(直至创建完所有内容行)àFooter&。值得注意的是,当我们把datagird&的allowpageing属性设为&true时,最先创建是的是分页导航行(Pager),而且在最后又重新创建了一次于分页导航行(Pager),首先创建pager行,可以理解为datagrid必须先依据Pager行才能知道现在要显示第几页,才好做下面的创建工作。但在最后又重新创建Pager行的原因是什么呢?还是请各位高手解答,我是没有搞清楚为什么要这样做?。另外我们要注意的是,即使我们没有设置datagrid&的AlternatingItemStyle样式,在创建行时,datagrid也是按照itemà&AlternatingItem的顺序创建,只不过它把ItemStyle样式应用在AlternatingItem(分隔行)上。并不是datagrid不创建AlternatingItem行,我在开始用datagrid的时候就是这样认为。创建行时首先触发itemcreated事件,每创建完上面的任何一行,都会触发itemcreated事件,通过itemcreated事件,我们可以定制datagird的任何类型的行。我们常在该事件中定制header(标题行),pager(分页导航行),及footer(脚注行),后续篇会我们讲到。执行完itemcreated事件后,一行的框架就打出来了,无需数据绑定的列都已完全建好了。接着要对需要进行数据绑定的列进行数据绑定,也就是把数据源的值赋到各个列中,也包括执行aspx页面的数据绑定表达式,就是像这种代码:&%#&&表达式&%&。完成数据绑定后,这时就触发了itemdatabound事件,在itemdatabound事件里,提供了我们访问datagrid的数据源的最后的机会,在itemcreated和itemdatabound事件里,我们可以通过(DataRowView)(e.Item&.DataItem),把e.Item..DataItem强制转换成DataRowView对象,然后我们就可以访问该数据源了。根据数据源中的数据,我们可以定制或改变datagrid某行或某列的显示值或显示样式。但要注意以下两点:一是创建pager行时并不会触发itemdatabound事件,因为pager行不进行数据绑定。二是只有在创建item行、AlternatingItem行、selecteditem行、edititem行时e.Item.DataItem才有值;创建其它类型的行时,e.Item.DataItem的值都为null。所以我们在处理e.Item.DataItem时必须先判断e.Item.itemtype属性为上述类型行时,才能取出数据源的值;否则会抛出“对象不能为null“的异常。执行完itemdatabound事件后,一行的创建工作就完成了。这时我们发现datagrid的items.count属性的值加了一,表示这一行创建完毕,加入了datagrid.items集合中。Datagrid循环地调用itemcreated和itemdatabound事件创建完所有的行后,就完成了datarid的创建工作。也就是说,执行完databinding事件后(itemcreated和itemdatabound是嵌套在databinding事件里执行的),整个datagrid就创建完了。如果我们要在这以后再访问datagrid里面的数据或内容,就只有通过datagird的items集合访问行数据,再通过datagirditem的cells集合访问datagrid的列数据或控件。如果此时你想通过datagirditem.dataitem属性访问datagrid的数据源,就会抛出”找不到对象或对象为null”的异常。因为在执行完itemdatabound事件后datagriditem.dataitem属性已经被置为null了。最后我们说说itemcommand事件,如果我们在datagrid的列模板中设置了buttoncolumn列或者说在itemtemplate中放置了linkbutton控件、checkbox控件、button控件等;所有这些控件引起页面提交时,都会触发datagrid的itemcommand事件,它们并不会触发它们本身的事件,例如button的click事件等。这种事件机制在asp.net里面称之为“冒泡事件“,在msdn上冒泡事件是这样解释的:不同于每个按钮单独引发一个事件,来自嵌套控件(这些控件放在datagrid容器中)的事件是“冒泡的”——也就是说,这些事件都将发送到容器中。该容器又引发一个带有参数的一般事件,名为&ItemCommand,它的参数使您可以发现是哪个控件引发了该事件。通过响应此单个事件(指只响应ItemCommand事件),可以避免不必要地为子控件编写单独的事件处理程序。关于“冒泡事件”请参考msdn:ms-help://MS.NETFrameworkSDK.CHS/cpguidenf/html/cpconwebformseventmodel.htm。至此,datagrid的原理篇就讲完了,下一个续篇我们具体讲解datagrid控件的应用。
写这篇文章之前,在csdn上经常看到有关从数据库中读出图片,并显示在网页上的问题,我查了好多资料,只有一种好的方案解决这个问题,就是用一个专门的页来生成图片,然后在目标页(引用图片)中放一个img控件,然后把img控件的src属性设成生成图片页的url,图片就可动态的显示在目标页上了。不知你有更好的方案没有?&&&&这几天我在做报表,表格的报表一般用datagrid或table web控件生成,因为这两个控件定制起来比较方便,基本上能满足实际需要。但很遗憾的是,我做的项目并不要求打印报表,所以没有经验可谈。做完整个项目后,我会研究一下打印的问题,以后的项目肯定要用,到时再作总结了。希望大家有好的解决打印的方案,贴出来给大家分享。关于用datagrid或table web控件定制报表的方案,在后续的篇章我会讲到,请关注!&&&&回到我们的主题,看了这篇文章后,也许你会感叹.net确实强大。因为.net里面提供了强大的画图功能,只是我们没有发现而已。有时间大家看看msdn,也许会发现好多好的东西。贴出源码之前,首先说明本源码是我从网上down下来的,我也不记得原作者是谁了。原来是英文的,我把它用中文作了注释,你把源码cut下来,放在某个页面的.vb文件中,就可以浏览其报表效果了。代码如下:Imports&System.DrawingImports&System.Drawing.ImagingPrivate&Sub&Page_Load(ByVal&sender&As&System.Object,&ByVal&e&As&System.EventArgs)&Handles&MyBase.Load&&&&&&&&Dim&i&As&Integer&&&&&&&&'创建一个bitmap对象,width=400,height=200像素&&&&&&&&Dim&bm&As&New&Bitmap(400,&200)&&&&&&&&Dim&g&As&Graphics&&&&&&&&g&=&Graphics.FromImage(bm)&&&&&&&&'set&canvas&color(设置图片的底色)&&&&&&&&g.Clear(Color.Snow)&&&&&&&&'display&graph&title(在指定位置并且用指定的&Brush&和&Font&对象绘制指定的文本字符串。画图片的标题)&&&&&&&&g.DrawString("Hours&per&day",&New&Font("Tahoma",&16),&Brushes.Black,&New&PointF(5,&5))&&&&&&&&Dim&yaxis(6)&As&Integer&&&&&&&&yaxis(0)&=&12&&&&&&&&yaxis(1)&=&7&&&&&&&&yaxis(2)&=&4&&&&&&&&yaxis(3)&=&10&&&&&&&&yaxis(4)&=&3&&&&&&&&yaxis(5)&=&11&&&&&&&&yaxis(6)&=&5&&&&&&&&Dim&xaxis(6)&As&String&&&&&&&&xaxis(0)&=&"Mon"&&&&&&&&xaxis(1)&=&"Tue"&&&&&&&&xaxis(2)&=&"Wed"&&&&&&&&xaxis(3)&=&"Thu"&&&&&&&&xaxis(4)&=&"Fri"&&&&&&&&xaxis(5)&=&"Sat"&&&&&&&&xaxis(6)&=&"Sun"&&&&&&&&'display&graph&legends(画图例)&&&&&&&&'图例的起始位置&&&&&&&&Dim&symbolLeg&As&PointF&=&New&PointF(335,&20)&&&&&&&&'图例说明文字的起始位置&&&&&&&&Dim&descLeg&As&PointF&=&New&PointF(360,&16)&&&&&&&&'用循环创建图例&&&&&&&&For&i&=&0&To&xaxis.Length&-&1&&&&&&&&&&&&'画图例,用矩形表示&&&&&&&&&&&&'画矩形&&&&&&&&&&&&g.FillRectangle(New&SolidBrush(GetColor(i)),&symbolLeg.X,&symbolLeg.Y,&20,&10)&&&&&&&&&&&&'画矩形的边框&&&&&&&&&&&&g.DrawRectangle(Pens.Black,&symbolLeg.X,&symbolLeg.Y,&20,&10)&&&&&&&&&&&&'画图例的说明文字&&&&&&&&&&&&g.DrawString(xaxis(i).ToString,&New&Font("Arial",&10),&Brushes.Black,&descLeg)&&&&&&&&&&&&'移动图例的坐标值,以例画下一图例&&&&&&&&&&&&symbolLeg.Y&+=&15&&&&&&&&&&&&descLeg.Y&+=&15&&&&&&&&Next&i&&&&&&&&'开始画饼图&&&&&&&&Dim&totalAng&As&Integer&&&&&&&&‘数据所占角度&&&&&&&&Dim&currentangle&As&Single&=&0&&&&&&&&'起始角度&&&&&&&&Dim&startangle&As&Single&=&0&&&&&&&&'计算总值&&&&&&&&For&i&=&0&To&yaxis.Length&-&1&&&&&&&&&&&&totalAng&=&totalAng&+&yaxis(i)&&&&&&&&Next&&&&&&&&For&i&=&0&To&yaxis.Length&-&1&&&&&&&&&&&&'计算角度&&&&&&&&&&&&currentangle&=&yaxis(i)&/&totalAng&*&360&&&&&&&&&&&&'画扇形&&&&&&&&&&&&g.FillPie(New&SolidBrush(GetColor(i)),&100,&40,&150,&150,&startangle,&currentangle)&&&&&&&&&&&&'画扇形的边框&&&&&&&&&&&&g.DrawPie(Pens.Black,&100,&40,&150,&150,&startangle,&currentangle)&&&&&&&&&&&&'移动扇形的坐标值,以例画下一扇形&&&&&&&&&&&&startangle&+=&currentangle&&&&&&&&Next&i&&&&&&&&'画整个图的大边框&&&&&&&&Dim&p&As&New&Pen(Color.Black,&2)&&&&&&&&g.DrawRectangle(p,&1,&1,&398,&198)&&&&&&&&'输出图片到输出流上,显示在客户端(格式成jpeg文件)&&&&&&&&bm.Save(Response.OutputStream,&ImageFormat.Jpeg)&&&&End&Sub&&&&'获取图例的颜色&&&&Private&Function&GetColor(ByVal&itemIndex&As&Integer)&As&Color&&&&&&&&Dim&objColor&As&Color&&&&&&&&Select&Case&itemIndex&&&&&&&&&&&&Case&0&&&&&&&&&&&&&&&&objColor&=&Color.Blue&&&&&&&&&&&&Case&1&&&&&&&&&&&&&&&&objColor&=&Color.Red&&&&&&&&&&&&Case&2&&&&&&&&&&&&&&&&objColor&=&Color.Yellow&&&&&&&&&&&&Case&3&&&&&&&&&&&&&&&&objColor&=&Color.Peru&&&&&&&&&&&&Case&4&&&&&&&&&&&&&&&&objColor&=&Color.Orange&&&&&&&&&&&&Case&5&&&&&&&&&&&&&&&&objColor&=&Color.Coral&&&&&&&&&&&&Case&6&&&&&&&&&&&&&&&&objColor&=&Color.Gray&&&&&&&&&&&&Case&7&&&&&&&&&&&&&&&&objColor&=&Color.Maroon&&&&&&&&&&&&Case&Else&&&&&&&&&&&&&&&&objColor&=&Color.Green&&&&&&&&End&Select&&&&&&&&Return&objColor&&&&End&FunctionEnd&Class&&&&在实际的应用中,我们新建一个页面,然后:&&&&&%@&Page&language="vb"&&%&&!DOCTYPE&HTML&PUBLIC&"-//W3C//DTD&HTML&4.0&Transitional//EN"&&&HTML&&&&&&HEAD&&&&&&&&&&title&项目总结之饼图报表源码篇&/title&&&&&&/HEAD&&&&&&body&bottomMargin="0"&leftMargin="0"&topMargin="0"&rightMargin="0"&MS_POSITIONING="GridLayout"&&&&&&&&&&form&id="sfgl_report"&method="post"&runat="server"&&&&&&&&&&&&&&TABLE&cellSpacing="0"&cellPadding="0"&width="765"&align="center"&border="0"&&&&&&&&&&&&&&&&&&TBODY&&&&&&&&&&&&&&&&&&&&&&tr&&&&&&&&&&&&&&&&&&&&&&&&&&td&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&br&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&div&align="center"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&img&runat="server"&id="img_report"&src=”&生成图片页的url”&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/div&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&br&&&&&&&&&&&&&&&&&&&&&&&&&&/td&&&&&&&&&&&&&&&&&&&&&&/tr&&/TBODY&&&&&&&&&&&&&&/TABLE&&&&&&/body&&/HTML&图片闪是正常的,因为它是用二进制流输出的,我以前做过从数据库读出html、word,显示到网页上,是这样解决的,你看看下面的代码,或许对你有启发,原理是多作了一道转换,我也不知道为什么这样会快,是经验得出来的:HttpContext.Current.Response.Clear();&&&&&&&&&&&&&&&&HttpContext.Current.Response.ContentType=open_file_application(file_type(str_table_name,str_blob_column_name,str_select_condition));&&&&&&&&&&&&&&&&System.IO.Stream&fs=HttpContext.Current.Response.OutputS&&&&&&&&&&&&&&&&int&fileDataCol&=&0;&&&&&&&&&&&&&&&&&&&&&&&&&Byte[]&b&=&new&Byte[(sdr_file.GetBytes(fileDataCol,&0,&null,&0,&int.MaxValue))];&&&&&&&&&&&&&&&&sdr_file.GetBytes(fileDataCol,&0,&b,&0,&b.Length);&&&&&&&&&&&&&&&&sdr_file.Close();&&&&&&&&&&&&&&&&&&&&&&&&&&&&cyc_data.scn_databaseconnection.Close();//转换成string&&&&&&&&&&&&&&&&string&s&=&System.Text.Encoding.Default.GetString(b);&&&&&&&&&&&&&&&&s&=&s.Replace(str_keyword,"&font&color='red'&"&+&str_keyword&+&"&/font&");//再转换成byte&&&&&&&&&&&&&&&&b=System.Text.Encoding.Default.GetBytes(s);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fs.Write(b,0,b.Length);&&&&&&&&&&&&&&&&fs.Close();&&&&&&&&&&&&&&&&HttpContext.Current.Response.End();没有直接写Response.Write(s)是因为这样太慢了,转换成byte[]型后,用文件流来写,速度快多了。
datagrid自定义分页是datagrid的一个重要的功能,datagrid自定义分页主要用于数据源较大时。因为数据源大(记录多),加载时间长,反应慢,耗服务器的资源。而且每显示一页就要重新加载所有的数据。而如果我们用自定义分页,则每一次只加载一页的记录,也就是只加载我们要显示的记录。这样加载数据时间短,反应快,节约服务器的资源。在做项目的过程中,我们也经常需要用到自定义功能。今天我们就说说怎样自定义分页。&&&&先看看datagrid的自定义分页的原理,它主要依据两个主要属性,第一个就是VirtualItemCount属性,它表示datagrid一共要显示多少条记录,它就是的作用是用于生成pager(分页导航行),通过结合另外两个属性pagesize和PageButtonCount,datagrid就知道要分成多少页了及当前要显示多少个分页按钮,我们不难得到总共要显示的总页数=(VirtualItemCount+pagesize-1)/pagesize;如要总页数&PageButtonCount,则显示总页数个按钮;如果总页数&PageButtonCount,则显示PageButtonCount个按钮,当然到了最后一页就只显示VirtualItemCount%&pagesize(总记录条数除以每页显示记录的余数)个按钮。另一个重要的属性就是datasource(数据源),自定义分页的一个重要的特点是显示数据源中所有的记录,如果数据源中有一条记录,则显示一条记录;如果数据源中有一万条记录,则它会显示一万条记录,可能你的机子就慢了&:&)。所以自定义最重要的一点是如何设置或获取数据源了。&&&&接下来,我们先说说自定义分页的主要步骤:1.&&&&设置datagrid的VirtualItemCount属性;2.&&&&获取datagrid的datasource(数据源);3.&&&&绑定数据到datagrid;4.&&&&设置新页的页码(datagrid.currentpageindex属性)。重复上述2,3,4步。下面我们以一个例子来讲解datagrid&的自定义过程。例子要求机子装有ms&sql&server&7.0&或&2000,当然还要能运行asp.net页了(废话)。我们先来写一个通用的存储过程,用于分页,返回某页的要显示的记录集,及一个输出参数--总的记录条数,但这个存储过程有缺陷,例如只能用于单表查询,必须要有条件语句等。CREATE&PROCEDURE&up_custompage&@vc_order_column_name&varchar(100),@vc_select_column_list&varchar(100),@vc_select_table_list&varchar(100),@vc_condition&varchar(100),@page_size&int,@current_page&int,@total1&int&output&/*&&&&(&&&&&&&&@vc_order_column_name&:表要排序列的列名,只能按一列排序,而且该列必须得在输出列表中;&&&&&&&&@vc_select_column_list&:返回列的列名列表;&&&&&&&&@vc_select_table_list:要查询的表名;&&&&&&&&@vc_condition:查询条件的字符串,必须要有查询条列,否则会抛出异常;&&&&&&&&@page_size:每页显示记录的条数;&&&&&&&&@current_page:当前页的页码;&&&&&&&&@total1:所有符合条件的记录的总数。&&&&&&&&构造的sql语句=select&top&每页显示记录的条数&*&from&(select&top&每页显示记录的条数&返回列的列名列表&from&要查询的表名&where&要排序列的列名&in&(select&top&每页显示记录的条数&X&当前页的页码&&要排序列的列名&&from&要查询的表名&where&查询条件&order&by&要排序列的列名)&order&by&要排序列的列名&desc&)&as&temp1&order&by&要排序列的列名&&&&)*/AS--声明要用到的变量,@temp1是正常的分页语句字符串,@temp2是最后一页的分页语句字符串,@page_total表一共有几页,@last_page--是最后一页的页码declare&@temp1&varchar(500),@temp2&nvarchar(500),@page_total&int,@last_page&int--构造获得总页的数的检索语句set&@temp2=N'select&@total2=count(*)&from&'&+&@vc_select_table_list&+&'&where&'&+&@vc_condition--执行检索语句,取得总的记录条数exec&sp_executesql&@temp2,N'&@total2&int&output&',@total1&output/*构造分页检索语句,基本原理是先取出@page_size*@current_page条记录,相当于是取出当前页及当前页前面的所有页面的记录然后取出当前面所要显示的记录,也就是反序排序后取前@page_size条记录;最后再反序排序(因为前面的顺序被反排过一次,现在再反排一次,正好是我们要的顺序),最后执行,返回结果集。*/if&@total1&0beginset&@page_total=(@total1+@page_size-1)/@page_size--如果当前页不是最后一页if&@current_page&@page_totalset&@temp1='select&top&'&+&cast(@page_size&as&varchar(4))&+&'&*&from&(select&top&'&+&cast(@page_size&as&varchar(4))&&+&'&'&+&@vc_select_column_list&+&'&from&'&+&@vc_select_table_list&+'&where&'&+&@vc_order_column_name&+&'&in&(select&top&'&+&cast(@page_size*@current_page&as&varchar(10))&+&'&'&+&@vc_order_column_name&+&'&from&'&+&@vc_select_table_list&+&'&where&'+&@vc_condition&&+&'&order&by&'&+@vc_order_column_name&+&')&order&by&'&+&@vc_order_column_name&&+&'&DESC)&as&temp1&order&by&'&+&@vc_order_column_name&else--最后一页只返回分页后的最后几条记录,也就是@total1%@page_size条记录beginset&@last_page=@total1%@page_sizeset&@temp1='select&top&'&+&cast(@last_page&as&varchar(4))&+&'&*&from&(select&top&'&+&cast(@last_page&as&varchar(4))&&+&'&'&+&@vc_select_column_list&+&'&from&'&+&@vc_select_table_list&+'&where&'&+&@vc_order_column_name&+&'&in&(select&top&'&+&cast(@total1&as&varchar(10))&+&'&'&+&@vc_order_column_name&+&'&from&'&+&@vc_select_table_list&+&'&where&'+&@vc_condition&&+&'&order&by&'&+@vc_order_column_name&+&')&order&by&'&+&@vc_order_column_name&&+&'&DESC)&as&temp1&order&by&'&+&@vc_order_column_name&end--执行检索exec(@temp1)endelsereturn-------------------------------------------------------------------------然后在新建一个aspx页面,代码如下:&%@&Page&language="c#"&Codebehind="custompage.aspx.cs"&AutoEventWireup="false"&Inherits="cyc_test.custompage"&%&&!DOCTYPE&HTML&PUBLIC&"-//W3C//DTD&HTML&4.0&Transitional//EN"&&&HTML&&&&&&HEAD&&&&&&&&&&title&custompage&/title&&&&&&&&&&meta&content="Microsoft&Visual&Studio&7.0"&name="GENERATOR"&&&&&&&&&&meta&content="C#"&name="CODE_LANGUAGE"&&&&&&&&&&meta&content="JavaScript"&name="vs_defaultClientScript"&&&&&&&&&&meta&content="&&&&&&&&&style&A&{&BEHAVIOR:&url(MouseOver.htc)&}&&&&HR&{&COLOR:&&HEIGHT:&2px&}&&&&.StdText&{&FONT-WEIGHT:&&FONT-SIZE:&9&FONT-FAMILY:&verdana&}&&&&.StdTextBox&{&BORDER-RIGHT:&black&1px&&BORDER-TOP:&black&1px&&FONT-SIZE:&9&FILTER:&progid:DXImageTransform.Microsoft.dropshadow(OffX=2,&OffY=2,&Color='gray',&Positive='true');&BORDER-LEFT:&black&1px&&BORDER-BOTTOM:&black&1px&&FONT-FAMILY:&verdana&}&&&&.Shadow&{&FILTER:&progid:DXImageTransform.Microsoft.dropshadow(OffX=2,&OffY=2,&Color='gray',&Positive='true')&}&&&&&&&&&/style&&&&&&/HEAD&&&&&&body&style="FONT-FAMILY:&arial"&bgColor="ivory"&MS_POSITIONING="GridLayout"&&&&&&&&&&form&id="custompage"&method="post"&runat="server"&&&&&&&&&&&&&&h2&项目总结之datagrid自定义分页篇&&&&&&&&&&&&&/h2&&&&&&&&&&&&&&asp:label&id="Label1"&runat="server"&font-bold="true"&cssclass="StdText"&当前路径:&&/asp:label&&asp:label&id="lblURL"&style="COLOR:&blue"&runat="server"&cssclass="StdText"&&/asp:label&&&&&&&&&&&&&&!--&Query&--&&br&&&&&&&&&&&&&&asp:label&id="Label2"&runat="server"&cssclass="stdtext"&Text="查询语句:"&&/asp:label&&asp:textbox&id="Textbox1"&runat="server"&cssclass="stdtextbox"&text="SELECT&employeeid,&firstname,&lastname,title&FROM&Employees&where&employeeid&0&order&by&employeeid"&width="765px"&Enabled="false"&&/asp:textbox&&&&&&&&&&&&&&hr&&&&&&&&&&&&&&!--&Show&the&information&--&&asp:datagrid&id="grid"&runat="server"&OnPageIndexChanged="PageIndexChanged"&AllowCustomPaging="True"&AllowPaging="True"&PageSize="5"&BorderWidth="1"&BorderColor="black"&BorderStyle="solid"&BackColor="White"&CssClass="Shadow"&GridLines="vertical"&CellSpacing="0"&CellPadding="2"&Font-Names="Verdana"&Font-Size="Smaller"&&&&&&&&&&&&&&&&&&PagerStyle&Font-Bold="true"&Mode="NumericPages"&BackColor="palegreen"&/&&&&&&&&&&&&&&&&&&AlternatingItemStyle&BackColor="#eeeeee"&/&&&&&&&&&&&&&&&&&&ItemStyle&BackColor="White"&/&&&&&&&&&&&&&&&&&&HeaderStyle&Font-Bold="True"&ForeColor="White"&BackColor="Navy"&/&&&&&&&&&&&&&&/asp:datagrid&&/form&&&&&&/body&&/HTML&再写后台的源代码:using&Susing&System.Cusing&System.ComponentMusing&System.Dusing&System.Dusing&System.Wusing&System.Web.SessionSusing&System.Web.UI;using&System.Web.UI.WebCusing&System.Web.UI.HtmlCusing&System.Data.SqlCnamespace&cyc_test{&&&&///&&summary&&&&&///&custompage&的摘要说明。&&&&///&&/summary&&&&&public&class&custompage&:&System.Web.UI.Page&&&&{&&&&&&&&protected&System.Web.UI.WebControls.Label&Label1;&&&&&&&&protected&System.Web.UI.WebControls.Label&lblURL;&&&&&&&&protected&System.Web.UI.WebControls.Label&Label2;&&&&&&&&protected&System.Web.UI.WebControls.TextBox&Textbox1;&&&&&&&&protected&System.Web.UI.WebControls.DataGrid&&&&&&&&&&&&&private&void&Page_Load(object&sender,&System.EventArgs&e)&&&&&&&&{&&&&&&&&&&&&//&第一次加载页时,初始化&&&&&&&&&&&&if&(!Page.IsPostBack)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&lblURL.Text&=&Request.Url&+&"&hr&";&&&&&&&&&&&&&&&&&&&&createdatasource(1);&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&//绑定datagrid的函数protected&void&createdatasource(int&current_page)&&&&&&&&{&&&&&&&&&&&&string&str_table_name,str_column_list,str_order_column,str_&&&&&&&&&&&&//查询的表名&&&&&&&&&&&&str_table_name="employees";&&&&&&&&&&&&//返回的列名列表&&&&&&&&&&&&str_column_list="employeeid,firstname,lastname,title";&&&&&&&&&&&&//排序列的列名&&&&&&&&&&&&str_order_column="employeeid";&&&&&&&&&&&&//查询的表件&&&&&&&&&&&&str_condition="employeeid&0";&&&&&&&&&&&&string&strConn&=&"DATABASE=NSERVER=UID=PWD=;";&&&&&&&&&&&&SqlConnection&conn&=&new&SqlConnection(strConn);&&&&&&&&&&&&//声明执行存储过程的SqlCommand&&&&&&&&&&&&&SqlCommand&scd_sel=new&SqlCommand("up_custompage",conn);&&&&&&&&&&&&scd_sel.CommandType=CommandType.StoredP&&&&&&&&&&&&//给存储过程的参数赋值&&&&&&&&&&&&SqlParameter&sp_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@vc_order_column_name",SqlDbType.VarChar,100);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=str_order_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@vc_select_column_list",SqlDbType.VarChar,100);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=str_column_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@vc_select_table_list",SqlDbType.VarChar,100);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=str_table_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@vc_condition",SqlDbType.VarChar,100);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=str_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@page_size",SqlDbType.Int);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=grid.PageS&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@current_page",SqlDbType.Int);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.I&&&&&&&&&&&&sp_temp.Value=current_&&&&&&&&&&&&sp_temp=scd_sel.Parameters.Add("@total1",SqlDbType.Int);&&&&&&&&&&&&sp_temp.Direction=ParameterDirection.O&&&&&&&&&&&&&&&&&&&&&&&&//执行存储过程&&&&&&&&&&&&SqlDataAdapter&sda=new&SqlDataAdapter();&&&&&&&&&&&&sda.SelectCommand=scd_&&&&&&&&&&&&if&(conn.State==ConnectionState.Closed)&&&&&&&&&&&&&&&&conn.Open();&&&&&&&&&&&&DataSet&ds=new&DataSet();&&&&&&&&&&&&sda.Fill(ds,"tb1");&&&&&&&&&&&&&&&&&&&&conn.Close();&&&&&&&&&&&&//设置VirtualItemCount属性&&&&&&&&&&&&grid.VirtualItemCount=(int)scd_sel.Parameters["@total1"].V&&&&&&&&&&&&//绑定数据源&&&&&&&&&&&&grid.DataSource=ds.Tables["tb1"].DefaultV&&&&&&&&&&&&grid.DataBind();&&&&&&&&}&&&&&&&&#region&Web&Form&Designer&generated&code&&&&&&&&override&protected&void&OnInit(EventArgs&e)&&&&&&&&{&&&&&&&&&&&&//&&&&&&&&&&&&//&CODEGEN:该调用是&ASP.NET&Web&窗体设计器所必需的。&&&&&&&&&&&&//&&&&&&&&&&&&InitializeComponent();&&&&&&&&&&&&base.OnInit(e);&&&&&&&&}&&&&&&&&&&&&&&&&///&&summary&&&&&&&&&///&设计器支持所需的方法&-&不要使用代码编辑器修改&&&&&&&&///&此方法的内容。&&&&&&&&///&&/summary&&&&&&&&&private&void&InitializeComponent()&&&&&&&&{&&&&&&&&&&&&&&&&this.grid.ItemCreated&+=&new&System.Web.UI.WebControls.DataGridItemEventHandler(this.grid_ItemCreated);&&&&&&&&&&&&this.grid.PageIndexChanged&+=&new&System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.PageIndexChanged);&&&&&&&&&&&&this.Load&+=&new&System.EventHandler(this.Page_Load);&&&&&&&&}&&&&&&&&#endregion&&&&&&&&//datagrid的ItemCreated事件,用于定制分页导航行&&&&&&&&private&void&grid_ItemCreated(object&sender,&System.Web.UI.WebControls.DataGridItemEventArgs&e)&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&ListItemType&elemType&=&e.Item.ItemT&&&&&&&&&&&&//定制分页导航行,样式为[1]&[2]&第&3&页&[4]&&&&&&&&&&&&if&(elemType&==&ListItemType.Pager)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&TableCell&pager&=&(TableCell)&e.Item.Controls[0];&&&&&&&&&&&&&&&&&&&&&&&&&&&&for&(int&i=0;&i&pager.Controls.C&i+=2)&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&Object&o&=&pager.Controls[i];&&&&&&&&&&&&&&&&&&&&if&(o&is&LinkButton)&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&LinkButton&h&=&(LinkButton)&o;&&&&&&&&&&&&&&&&&&&&&&&&h.Text&=&"[&"&+&h.Text&+&"&]";&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&Label&l&=&(Label)&o;&&&&&&&&&&&&&&&&&&&&&&&&l.Text&=&"第"&+&l.Text&+&“页”;&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&}&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&&&&&//页选中(分页)事件&&&&&&&&public&void&PageIndexChanged(object&source,&System.Web.UI.WebControls.DataGridPageChangedEventArgs&e)&&&&&&&&{&&&&&&&&&&&&grid.CurrentPageIndex&=&e.NewPageI&&&&&&&&&&&&//页码值是从零开始的,所以要加一&&&&&&&&&&&&createdatasource(grid.CurrentPageIndex+1);&&&&&&&&}&&&&}}&&&要运行上面的示例,请按上面的顺序先创建存储过程,再写页面的代码,最后是源代码。示例参考了《构建Web解决方案---应用ASP.NET和ADO.NET》中的分页思路。在本机调试通过。大家只要明白存储过程分页的思想就可以了。如果大家有更好的方案,请提出来,也许你的更好!&&&这一段时间又开始了新的项目,所以这篇文章写得比较仓促,可能有些地方讲得不明白,大家可以提问和讨论。希望对大家有所帮助。ALTER&PROCEDURE&up_custompage&@vc_order_column_name&varchar(100),@vc_select_column_list&varchar(100),@vc_select_table_list&varchar(100),@vc_condition&varchar(100),@page_size&int,@current_page&int,@total1&int&output&/*&&&&(&&&&&&&&@vc_order_column_name&:表要排序列的列名,只能按一列排序,而且该列必须得在输出列表中;&&&&&&&&@vc_select_column_list&:返回列的列名列表,可以为多个列;&&&&&&&&@vc_select_table_list:要查询的表名及关联表的连接;&&&&&&&&@vc_condition:查询条件的字符串,必须要有查询条列,否则会抛出异常;&&&&&&&&@page_size:每页显示记录的条数;&&&&&&&&@current_page:当前页的页码;&&&&&&&&@total1:所有符合条件的记录的总数。&&&&)*/AS--声明要用到的变量,@temp1是正常的分页语句字符串,@temp2是最后一页的分页语句字符串,@page_total表一共有几页,@last_page--是最后一页的页码declare&@temp1&varchar(500),@temp2&nvarchar(500),@page_total&int,@last_page&int--构造获得总页的数的检索语句set&@temp2=N'select&@total2=count(*)&from&'&+&@vc_select_table_list&+&'&where&'&+&@vc_condition--执行检索语句,取得总的记录条数exec&sp_executesql&@temp2,N'&@total2&int&output&',@total1&output/*构造分页检索语句,基本原理是先取出@page_size*@current_page条记录,相当于是取出当前页及当前页前面的所有页面的记录然后取出当前面所要显示的记录,也就是反序排序后取前@page_size条记录;最后再反序排序(因为前面的顺序被反排过一次,现在再反排一次,正好是我们要的顺序),最后执行,返回结果集。*/if&@total1&0beginset&@page_total=(@total1+@page_size-1)/@page_size--如果当前页不是最后一页if&@current_page&@page_total&or&@total1%@page_size=0set&@temp1='select&top&'&+&cast(@page_size&as&varchar(4))&+&'&*&from&(select&top&'&+&cast(@page_size&as&varchar(4))&&+&'&'&+&@vc_select_column_list&+&'&from&'&+&@vc_select_table_list&+'&where&'&+&@vc_order_column_name&+&'&in&(select&top&'&+&cast(@page_size*@current_page&as&varchar(10))&+&'&'&+&@vc_order_column_name&+&'&from&'&+&@vc_select_table_list&+&'&where&'+&@vc_condition&&+&'&order&by&'&+@vc_order_column_name&+&')&order&by&'&+&@vc_order_column_name&&+&'&DESC)&as&temp1&order&by&'&+&@vc_order_column_name&else--最后一页只返回分页后的最后几条记录,也就是@total1%@page_size条记录beginset&@last_page=@total1%@page_sizeset&@temp1='select&top&'&+&cast(@last_page&as&varchar(4))&+&'&*&from&(select&top&'&+&cast(@last_page&as&varchar(4))&&+&'&'&+&@vc_select_column_list&+&'&from&'&+&@vc_select_table_list&+'&where&'&+&@vc_order_column_name&+&'&in&(select&top&'&+&cast(@total1&as&varchar(10))&+&'&'&+&@vc_order_column_name&+&'&from&'&+&@vc_select_table_list&+&'&where&'+&@vc_condition&&+&'&order&by&'&+@vc_order_column_name&+&')&order&by&'&+&@vc_order_column_name&&+&'&DESC)&as&temp1&order&by&'&+&@vc_order_column_name&end--执行检索exec(@temp1)endelsereturn
在做项目的过程中看了几本书,包括《asp.net高级编程》(Wrox出版)、《构建Web解决方案---应用ASP.NET和ADO.NET》、《Applied&Microsoft&.net&framework&programming》中文版、《javascript&权威指南》(第三版)这几本书,分别说说这几本吧,第一本看了一半(看了前10章及后面的13、15章),至今还没有看完,感觉是讲得比较全,什么东西都说了,但说的不得不够深,不够贴近实际应用,但给我引入了门,知道常用控件的使用及一些常用的类,如dataset、sqldatareader等,所以这本书也值得一看。第二本是个人认为的在做项目中最实用、最有用的一本,我基本上看完了这一本书。看过这本书的人都知道这本书基本上都是围绕着datagrid讲解的,而我们在做项目的时候用得最多的无非也是datagrid,datalist这些与数据库密切关连的控件,所以看了这本书以后,受益匪浅,对datagrid的使用就上了一个档次。Datalist其实和datagrid相差不大,自然也就提升了。上面还结合例子讲了一些其它控件及类的使用。总结下来就是这本书讲得深,结合例子讲(可以在网站上下它的源码),贴近于实际应用。强烈给推荐大家。第三本只看了三分之一,因为看起来实在是太费力了,也许基础比较差,挺费力的看了前面的几章,回过头来想想,好象没什么印象,也不知道书上说了些什么,不知哪位大侠指点一下,如何才能看得懂该书。我想边看英文版,边看中文版,无耐英文实在太差,看到英文就头痛,所以就一直没往下面看。看来得下决心学英文了。所以这本书就不敢提什么建议了。最后一本是因为做web项目,不可能不和客户端打交道,所以javascipt是不可缺少的,这本书是作参考,用到的时候就翻,相当于一本javascript的字典,还是可以的。&&&&做项目的时候,忙得要命,总是在想,项目完了以后,我要好好的学习自定义控件开发、数据报表、XML、javascrpt、项目管理……自定义控件:不知大家开发过没有,相信还是有很多人自己研究和开发过,有什么经验,请拿出来和大家一起分享。我计划看msdn学习一下,到时再和大家一起交流,请问大家有什么好书、好的学习网址,有50分奖励哦。&&&&数据报表:主要是柱形图、曲线图、饼图的开发,这两天都在研究这个,从网上下了一些源码,好象可以通过system.system.drawing.Graphics类可以画图。学好了再和大家交流。&&&&XML:因为发现许多的应用中都可以用XML实现,如:不刷新页面在客户端和服务器间来回传递数据,XML作为中间层存储数据等;这是我最想学的东西了,一直没时间,还有就是不知道怎么入门。在网上也下了好多本书,但是希望结合.net来学。所以希望大家推荐好书、好的网站,最好还是书,这样学起来快些。100分赏金。&&&Javascript可以慢慢学,用的时候看看书应该没有问题,它是asp.net的基础,当然也不能少了。&&&最后是项目管理/软件工程了,做项目有时很气就是,项目需求老是在变,变一次程序就要改一次,挺烦人的。如果在早期作需求的时候充分考虑到需求的变更,或考虑得详细,周全一点,那么在编码时就不必那么费劲了。所以做需求分析及系统分析的工作是非常重要的。大家都说30岁就不能做程序了,我虽然不赞同这种说法,但也赞同不可能一辈子做程序员,毕竟做程序员是靠卖脑细胞谋生的,人老了,脑细胞就不多了,无法再卖了。考虑以后的问题,做项目管理或系统分析是不错的选择。但是难啊!还得学好多的东东,真是学不完啊。最近就买了《人月神话》、《软件工程—实践者的研究方法》看。只看了《人月神话》,感觉还是不错了,上面的话用在实际中还是挺有道理的。引入经典的一句:人/月如果成正比,那是软件工程的神话,天方夜谭。有道理啊。《软件工程—实践者的研究方法》还没开始看,相信还是不错。毕竟是经典之作啊。但我还推荐大家一本好书,自己觉得非常不错,就是电子工业出版社的《软件需求》,国外经典教材系列。结合例子讲。我看了一半,来不及总结。大家可以到书店去翻翻。电子书下载网址大全:www.pcbookcn.com&&非常书城:帝华咨讯:海阔天空:ebook-博士网图书库&&ebook电子图书搜索网&&ebook-电子图书下载中心ebook-非常书城ebook-计算机图书大全ebook-互动出版网ebook论坛-E世代家园论坛--夏季版ebook-山海程序ebook-月夜我飞翔ebook-中华电脑书库***)&&****)&&(软件加书籍下载&&****)&&(*)&&(**)&&(互动出版社,需MONEY)****&&&&&(专门的书籍下载网&&*****)&&(软件加书籍下载&&****)&&(当当网上书店,NEED&&MONEY&&****)&&(黄金书屋&&****)&&(博士网****)&&(***)&&***)&&(****)&&www.epubcn.com&&&&(英文斑***)&&(软件加书籍下载&&***)&&***)&&****)&&*****化境&&ftp.gargoylewiz.dynip.com&&···博士网&&****白菜乐园&&www.3322.net/~shii/TNT/crk_a.htm&&&&《oracle9i初学者指南》&&《oracle8i初学者指南》&&&下面是一些电子书籍的下载地址&&
在项目中,调试是重要的,作为一个程序员,如果你说你不会调试,那你当然就不是一个合格的程序员,所以我想写一篇文章来总结一下asp.net的调试。正好在做完项目时,上msdn看了一下,就发现msdn杂志上的这篇文章。但却是英文的。我英文本来就很差。所以看英文文章很吃力,但为了学习和提高。也就硬着头皮上了。我是边用金山词霸指着,边翻译。历时一个月才把它翻出来。累啊!可能有许可地方译得不对,希望英文好的同志指正。万分感谢!&&&&原文网址:由于在论坛中不能贴图片,所以建议你把所有的文字都拷到word中,把原文的图片下载下来,然后插入到相应的位置,然后再阅读本文。原文还可以下载源代码,下下来后,你可以本机试试。我试了一下,mytracer工具没有应用成功,我也不知道是什么地方没有设置对。希望你看了本文以后,如果用成功了。请说说怎么用。另外就是我在最后把mydebugtool用户控件的源码也帖出来了。希望对你有帮助。&&&&我在看完本文后,感觉还有些收获的。你看完后,请谈谈你的感想,下面请看文章。MyTracer跟踪监视器和asp.net的跟踪应用NET&Framework自带了许多跟踪和调试程序的工具。我并不想和大家讲整个的调试工具;我只想说明在开发软件周期中,&跟踪器和调试器与一般的应用程序不一样,因为它们是交互式的工具,它们一般都与开发环境整合在一起,例如vs.net。&&&&Systems.Diagnostics命名空间包括了两个类,一个是trace,另一个是debug,它们的方法都能用于输出代码执行结果的信息。这种特性对跟踪数据错误,监视数据溢出和判定条件,及收集各种数据是非常有用的。trace和debug类功能相似,都是比较特殊的模块,称为接收器。&&&&跟踪Windows&程序和asp.net程序的工具有很大的区别。具体的说,Windows&Forms程序的跟踪机制是基于可以定制接收者的模块并加以扩展,而asp.net程序的跟踪机制是不可扩展的,ASP.NET子系统只提供了一个可定制的tracing模块。当page在跟踪模式下运行时,将附加的输出各种跟踪信息表。这些表将显示性能、请求和状态等有关信息。不管你是否写了输出跟踪消息,那些表总是会附加的输出到浏览器中。&&&&Vs.net提供了一个功能强大的整合的调试器,它支持cutting-edge特性,如断点,快速监视及各种通过代码分步执行的方法。调试器是捕获错误及使代码错误最小化的理想的工具。因此,如果你用vs.net创建工程的话,就不必再问什么了。但是如果你不用vs.net的呢?如果你用的是不具备调试工具的编辑器的话,在这种情况下,编辑跟踪调试工具对程序健壮性就非常重要了。&&&&在这种情况下,我们首先要研究整个ASP.NET应用程序的跟踪子系统,然后写一个window应用程序,以执行一个给定的页和收集它运行时的信息,如页的视图状态(viewstate),请求内容(request&context),和全局对象(如cashe,Application,Session)。我把这个应用程序叫MyTracer&。MyTracer应用程序能与vs.net整合应用,在测试时也可以作为浏览器。我要指出的是,在某些地方我运用了没有经过验证的类。它不会影响代码,但是那些类在以后可能会有所改变。&&&&允许asp.net页面调试&&&&虽然你可以在web.config文件中增加trace配置段以在配置程序级跟踪(也就是在该程序下的所有网页都具有跟踪功能),但是我们没有必要跟踪每一个页面。对于一个非常大的项目来说,你可以在web.config文件中用下面代码设置trace功能:&&&&&&configuration&&&&system.web&&&&&&&trace&enabled="true"&pageOutput="true"&/&&&&/system.web&&/configuration&&&&&enabled属性设置是否允许跟踪,pageOutput属性设置是否允许在页面中显示跟踪输出的信息。如果pageOutput属性设置为false时(默认值),跟踪输出自动发送到asp.net的跟踪工具---&trace.axd中。在项目要结束时,你只要把trace配置段的上述两个属性设为&false,就关闭了各个级别的跟踪,页面就不会再输出跟踪信息了。&&&&如果你只想跟踪某个页面,你可以用页面的@page指令的trace属性来设置跟踪。trace属性默认值为false。当你把它设为true时,系统和自定义的信息都可以通过单击trace按钮显示在页面上,如图1所示:&&&&&&&&&&&Figure&1&System&and&Custom&Tracing要注意的是,跟踪信息会作为当前页面的一部分输出到访问该页的浏览器中。正如你想的一样,某些跟踪信息表显示由页生成的跟踪信息。另外的一些表显示请求的详细信息、控件树及一些有用的集合,如cookeies,headers(标头集合),form&values(窗体集合)和server&variables(服务器变量)。如果session和application状态不为空,它们的内容也会显示出来。view&state的内容和Cache对象不会直接的被跟踪。在mytracer(作者做的windows应用程序,用于调试跟踪)里面会跟踪他们。@Page指令支持TraceMode属性,让你可以选择怎样排序显示跟踪信息。两个有用的属性是SortByCategory(按类型排序)及SortByTime(按时间排序)。默认情况下,跟踪信息是按产生的顺序显示的。如果你把TraceMode属性设为SortByCategory,跟踪信息将按类别名排序显示。跟踪信息行是按输出跟踪信息的方法进行分类的。&输出跟踪信息&asp.net页面用TraceContext类暴露的方法生成其跟踪信息。在执行一个http请求时,asp.net会创建一个TraceContext类的实例。Tracer对象(TraceContext类的实例)通过httpcontenxt&类的trace属性和page类的trace属性暴露出来。&&TraceContext类有一个很简单的接口,它只有两个属性和一些方法。两个属性分别是IsEnabled&和&TraceMode属性。IsEnabled是一个布尔值的只读属性,用于设置是否允许跟踪。它的值受@page指令的trace属性和web.config配置文件的trace配置段的影响。跟踪信息按TraceMod属性的设置的排序方式排序后显示。TraceMode的属性值是一个TraceMode枚举类型,它包括SortByCategory&和SortByTime这两种枚举值。&要输出跟踪信息,你可以用TraceContext类的write或warn方法。这两种方法都有三次重载。它们非常相似。只有一点不同,warn方法总是以红色的字输出信息。&&&write方法有三次重载:&&Public&Sub&Write(msg&As&String)Public&Sub&Write(cat&As&String,&msg&As&String)Public&Sub&Write(cat&As&String,&msg&As&String,e&As&Exception);&&&&最简单的重载方法只输出指定的文字信息。在第二个重载方法中,第一个字符型参数表示你想用哪种类型名来输出参数二中指定的信息。类型名用于对跟踪信息排序,你可以用能够清楚表示信息的任何文字作为它的类型名。第三个重载方法增加了一个输出异常信息的对象,在这种情况下,跟踪信息由系统的异常信息及你指定的错误信息串接而成。虽然通过write和warn方法可以在html页中输出跟踪信息,但是不能对文字应用样式表。信息字符串是以纯文本的形式输出的,如果你试图对它应用任何特殊的格式,例如&b&标签,你将在跟踪信息行上看到&b&标签的字符串,而不是加粗显示效果。如果没有完全限定名称,&aspx页面及其后台类文件都不能使用Asp.net的tracer对象,页面中的自定义控件和它的后台类也不能够直接的访问跟踪子系统,其它的类则更不能。但是可以在你的后台代码类中声明一个外在的类来代理完成跟踪页面的任务。那么代理类怎么在asp.net页中执行跟踪呢?在这些类里,页面的跟踪对象是无效的,至少在外部类中想要在当前的http请求中输出跟踪信息必须要用下面的表达式来调用tracer:System.Web.HttpContext.Current.Trace.Write(cat,&msg)&&&&注意asp.net的跟踪系统不支持把它自己作为跟踪信息的接收者,也不支持诊断跟踪片断注册。另外也没有办法去修改哪些显示跟踪数据的标准表,如果你想修改或增加其它的跟踪信息表,你只有通过其它的方法了。跟踪查看器(trace&viewer)&&&&asp.net的trace&viewer&支持程序级跟踪。一旦程序允许跟踪,每次请求页面时,页面都会发送指定的跟踪信息到该查看器。你可以通过请求应用程序根目录下的trace.axd页面看到跟踪查看器(如图2)。如前所述,你可以在web.config文件的trace配置段中设置允许跟踪。如下代码所示:&&&configuration&&&&system.web&&&&&&&trace&enabled="true"&/&&&&/system.web&&/configuration&&&&&pageOutput属性为false时,只有跟踪查看器才能收到跟踪信息,每个页面都可以用@Page指令的trace属性覆盖程序级的跟踪设置。跟踪查看器只缓存requestLimit(trace配置段中的一个属性)个请求信息。&&Figure&2&Viewing&the&Trace&Viewer&&&&简单的说,asp.net跟踪查看器担任总控制台的角色,它收集了在应用程序中所有的页面的跟踪信息。每一次客户端的请求--不能大于requestLimit设定的值,都会在跟踪器中生成一条记录以供参考,除非跟踪器的缓存被清除(如图2)。&&&&你可以通过在应用程序的根目录下请求trace.axd页的url来激活跟踪查看器。AXD是特殊的资源类型,它是aspnet_isapi.dll&ISAPI应用程序的扩展名,如图3所示。首先,跟踪查看器显示如图2所示的页,然后,跟踪查看器会自动跟踪所有的请求并缓存请求的页的所有信息直到它们被清除为止。当请求达到上限时(requestLimit设定的值),其它的请求将不会被缓存,除非你手工把它清除。你可以单击每个请求的跟踪信息行中的“查看详细信息”链接查看其详细的跟踪信息。&Figure&3&Requesting&a&Trace&&&&asp.net跟踪的内部机制是完美的,它提供了很好的跟踪页面运行时信息的办法,并允许你声明和校验动态的内部的值。另一方面,它不会显示所有你想跟踪的信息及令人讨厌的基于文本的界面。跟踪信息是依据页面生命周期中最后的一个事件触发后生成的。众所周知,asp.net页面是从HttpRuntime环境下得到一个请求事件后开始工作的。从Page_Init到Page_Unload事件,也包括Page_Load和Page_PreRender事件记录了页面的整个生存周期。当页面的最后一个事件触发时,浏览器的html还没有被预呈现。在页面呈现时,html代码临时缓存在输出流中,等待注册的处理模块作进一步的处理。这时,页面中的代码不能访问附加输出的跟踪html信息。这种封闭的结构,连同我们不喜欢的基于文本的用户界面一起封装起来,也给了我们另一个可选的方案。&&&&在讨论mytracer之前,我先说明一点,是关于asp.net&的页面跟踪。你应注意把页面的trace属性设为false,那么页面代码中的调试语句(trace.write或trace.warn)就无效了(不会在页面中输出调试信息)。实际上不管是否允许跟踪,write和warn方法都会执行。这也许在执行程序的时候有影响,但是它可以忽略不计,尤其是在没有用代码进行跟踪时,就更不会有什么影响了。要允许或不允许跟踪最简单的办法是在web.config文件中设置trace配置段,也可通过跟踪查看器设置。当接到用户的反馈时(例如不能停止应用程序)要跟踪应用程序,用上述的方法重新激活跟踪,按条件输出跟踪信息。MyTracer工具&&&&在asp.net&1.x可以选择另一种方法来写跟踪工具,你可以把它当成一个http模块来写,及用HttpApplication事件和ASP.NET对象模式去收集程序运行时要显示的信息。另外,你还可以使它暴露方法和事件以便与页面相结合。在本期栏目中,我将用一个不同的方法开发一个的windows应用程序与vs.net集成使用。最后,mytracer是一个windows应用程序,它嵌入了WebBrowser&ActiveX&组件用于显示web页面,并且运用了web&service作为asp.net和windows的桥梁。图4显示了该工具运行一个示例页的情况:&Figure&4&MyTracer&Tool&&&&该工具可以运行及显示指定的页。如果page页已配置了MyTracer(下面会讲怎么在页中配置mytracer,使页面可以被mytracer跟踪),那么页面指定的信息将输出,这些信息是用位于同一虚拟目录web&Serveice作为跟踪应用程序生成的。&Windows&form应用程序处理DocumentComplete事件,并与web&service连接下载已准备好的asp.net运行时的信息,然后它简单的组织生成各种信息表,表中输出各种信息,如:session,&Application,&Cache,&view&state,&input&form,&server变量,及页面的控件树等。&&&&Mytracer由三个部分组成----windows&forms&应用程序(如图4所示),前述的web&service,以及被跟踪页面必须包含的web&用户控件。用户控件(mydebugtool.ascx)与页面的生存周期中的主要事件关联并把跟踪信息存入dataset对象中。当页面卸载时,dataset被存入数据库中,这类似于asp.net中的用SQL&Server™管理session状态。Web&service从数据库中重新获得该对象(dataset对象),Windows&Forms程序再从web&service中下载该对象。数据总是以dataset的形式一级级的传递,直到它显示给用户看。数据库和web&service都有比较简单的结构。不同的是,dataset作为一个XML&DiffGram对象保存下来的,所以它被当成一个字符串处理和移动。图5描述了该工具的整个框架结构:&&&&&&Figure&5应用&MyTracer&&&&要应用MyTracer,页面中必须要包含MyDebugTool用户控件。该控件有一个简单的用户界面,它告诉用户该工具已被激活(可以在页面的看见标题文字)。该控件与Page_Unload和&Page_PreRender事件关联,缓存程序和请求指定的信息,如Application,&Cache和&Session。数据被存在dataset对象中,dataset对象在该用户控件的构造函数中被实例化,并在page卸载时被长久的保存在SQL&Server&数据库中。要在给定一个的asp.net页中应用MyTracer,必须在页面中注册该控件,可以通过@Register注册用户控件:&&&&&&%@Register&TagPrefix="msdn"&TagName="debug"&Src="MyDebugTool.ascx"%&&&&&&注意,TagPrefix&和TagName属性为任何值,但用户控件必须与应用程序在同一个Web&domain中。你可以在页面中的任何地方放置该用户控件的实例,甚至在最顶端。注册完后,你可以用下面的代码声明用户控件的一个实例:&msdn:debug&runat="server"&ID="mytracer"&UserKey="dino"&/&&&&&ID属性不是必须的,但是,在后面你可以看到。如果你想要访问视图状态信息的话,你必须要设置ID属性。用户控件的公共属性UserKey用于唯一标识数据库的行(表的主键),它必须是唯一的。除此以外,就没有其它的限制了。当你完成上述的配置时,在浏览器中打开指定的页面。该页面显示一个蓝底黑字的信息条文字,说明页面应用了MyTracer工具。当页面发送到浏览器,数据库就会被更新。可以通过ConnString属性设置数据库的连接字符串。MyTracer默认调用SQL&Server一个名为InternalCache的表。该表有两个字段:UserKey和Data,userkey为字符串型;Data为text型,它们被存在diffgram格式的dataset中,dataset对象包含了所有收集到的信息。写入数据库时,假设数据库中已存在指定的userkey。换种说法,只执行update语句而从不执行insert语句。对任何的数据库服务器,只有用下面的查询语句才能被理解和执行:SELECT&data&FROM&internalcache&WHERE&userkey=@TheUser&&&&用户控件在临时的dataset中创建了许多的表,所有的这些表都有两个string类型的列,分别叫:Key和Value。这些表保留了下面集合的内容:Request.Headers,&Request.Form,&Request.Cookies,&Request.ServerVariables,Application,&Cache,&Session,&加上页面的view&state&和controls。图6中所示的代码演示了关于怎样重新获得Cache和页面控件的信息。特别地,cache对象包含user和system两种信息。如tracer所示,在集合中的一些slot通过服务器的http&运行时和指定的内部类收集运行时的信息。例如,如果session&状态配置成存在本地的asp.net进程中(默认的设置),session集合在缓存中作为一个单独的对象保存。在session集合内部叫SessionStateItem,如图7所示:Figure&6&Retrieving&Cache&and&Page&Control&Information//&*****************************************************************//&从缓存中加载信息private&void&LoadFromCache(DataSet&info){&&&&DataTable&dtCache&=&CreateKeyValueDataTable("Cache");&&&&foreach(DictionaryEntry&elem&in&Page.Cache)&&&&{&&&&&&&&if&(ShowAll)&&&&&&&&{&&&&&&&&&&&&AddKeyValueItemToTable(dtCache,&elem.Key.ToString(),&&&&&&&&&&&&&&&&&DisplayFormat(elem.Value));&&&&&&&&}&&&&&&&&else&&&&&&&&{&&&&&&&&&&&&&&&&string&s&=&elem.Key.ToString();&&&&&&&&&&&&if&(!s.StartsWith("ISAPIWorkerRequest")&&&&&&&&&&&&&&&&&&&&!s.StartsWith("System"))&&&&&&&&&&&&&&&&AddKeyValueItemToTable(dtCache,&elem.Key.ToString(),&&&&&&&&&&&&&&&&&DisplayFormat(elem.Value));&&&&&&&&&}&&&&}&&&&dtCache.AcceptChanges();&&&&info.Tables.Add(dtCache);&&&&}//&*****************************************************************//&*****************************************************************//&从页面的控件集合中加载信息private&void&LoadFromPageControls(DataSet&info){&&&&HtmlForm&theForm&=&&&&&&&&&DataTable&dtControls&=&CreateKeyValueDataTable("Controls");&&&&for&(int&i=0;&i&Page.Controls.C&i++)&&&&{&&&&&&&&if&(Page.Controls[i]&is&HtmlForm)&&&&&&&&&&&&theForm&=&(HtmlForm)&Page.Controls[i];&&&&&&&&AddKeyValueItemToTable(dtControls,&Page.Controls[i].ToString(),&&&&&&&&&&&&&Page.Controls[i].ClientID);&&&&}&&&&dtControls.AcceptChanges();&&&&info.Tables.Add(dtControls);&&&&if&(theForm&==&null)&&&&&&&&&&&&&&&&&&&&DataTable&dtFormControls&=&CreateKeyValueDataTable("FormControls");&&&&for&(int&i=0;&i&theForm.Controls.C&i++)&&&&&&&&AddKeyValueItemToTable(dtFormControls,&&&&&&&&&&&&&theForm.Controls[i].ToString(),&&&&&&&&&&&&&theForm.Controls[i].ClientID);&&&&dtFormControls.AcceptChanges();&&&&info.Tables.Add(dtFormControls);&&&&}//&*****************************************************************Figure&7&System&Items&Stored&in&Cache&在图7中你可以看到所有保存在cache中的系统项都有一个以"System"或者&"ISAPIWorkerRequest.开头名称。如果你想看到这些项---位于cache中的程序的session变量,设置MyDebugTool的showall属性为false。在图7中,在value列中的一些值用括号括起来,它表示该项包含的是一个对象,括号中的字符串表示该对象的类型名或者是该对象的实际值。对象是通过下面的这个函数显示的:string&DisplayFormat(object&o){&&&//如果o是一个string或者是基元类型,则返回它的实际值,否则返回对象的类型名&return&(o&is&string&||&o.GetType().IsPrimitive&&&&&&&?Convert.ToString(o)&&&&&&&&:"{&"&+&o.ToString()&+&"&}");}&&&&如果&Type为基元类型之一,则IsPrimitive属性为&true;否则为&false。基元类型是&Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Char、Double&和&Single。注意在这个文本中是不考虑基元类型的,它们把它当成是一个引用类型,并把它当作是system.string类的一个实例。用于输出所有存储在cache中的信息的代码,类似于用于输出application,&Session,&Request&collection的代码,都是很简单的。&&&&要列出页面中所有的控件,你可以通过遍历Page.Controls集合。注意,该集合只包含的页面中的第一层控件,并不是页面中所有的控件。也就是在整个html模式下的&body&元素(标签)下的所有的直接的子控件。实际上,如果你遍历Page.Controls集合,你将会得到一个非常少的控件---主要是literals和asp.net中唯一的一个form控件。在设计时,所有的服务器端控件都包含在一个服务器端的form控件中。要访问所有的这些控件,你必须对form控件的controls集合执行第二次循环。MyTracer工具显示了每个控件的id。要注意的是,在设计时,所有服务器端控件都必须分配一个客户端id。这个id必须是唯一的,它通常都在基于服务器的id属性值分配的。如果该服务器端控件没有id,asp.net运行时会为它生成一个唯一的值。要访问它的客户端id,&就用它的clientid属性。辅助的web&service&&&&从架构上讲,&web&service相当有用,因为它搭建了asp.net与windows应用程序或者asp.net应用程序与asp.net应用程序之间的桥梁。在mytracer工具中,web&service担任了连接windows&应用程序与asp.net页面跟踪应用程序的作用。它提供了一个命令界面让windows应用程序获得asp.net应用程序中指定的信息。在这里我用web&service是因为它非常容易与其它已存在的程序共存。例如,你可能在程序中用了一个基于windows服务的外部程序,它通过remoting操作,从用户控件中获得数据,并在windows&form应用程序中处理该数据。同样的,选择用数据库也是个人喜好,你可以用服务全局变量(内存)替代。总的说来,StateServer&和&SqlServe两项,都能被mytrace复制。&&&&Web&service的编辑非常简单(如图8所示)。Getinfo方法执行一个数据库查询并返回一个描述原始的dataset对象的xml&diffgram&格式的string。GetInfo方法序列化该string,然后用dataset对象的readxml方法重建一个有效的dataset对象,接着,返回新建的dataset对象,注意,如果userkey在数据库中不存在,那么web&service返回的值可能不对,理想情况是你应该过滤userkey字段值,也可以用参数化的查询。Figure&8&Web&Service&Programming&Interface&%@&WebService&language="C#"&class="MyDebugTool"&%&using&Susing&System.Web.Susing&System.Dusing&System.IO;using&System.Data.SqlC[WebService(Namespace="MsdnMag.CuttingEdge")]public&class&MyDebugTool&{&&&&[WebMethod]&&&&public&DataSet&GetInfo(string&connString,&string&userKey)&&&&{&&&&&&&&SqlDataAdapter&adapter&=&new&SqlDataAdapter(&&&&&&&&&&&&"SELECT&data&FROM&internalcache&WHERE&userkey='"&+&&&&&&&&&&&&&userKey&+&"'",&connString);&&&&&&&&DataTable&tmp&=&new&DataTable();&&&&&&&&adapter.Fill(tmp);&&&&&&&&DataSet&ds&=&new&DataSet();&&&&&&&&StringReader&reader&=&new&&&&&&&&&&&&&StringReader(tmp.Rows[0]["data"].ToString());&&&&&&&&ds.ReadXml(reader);&&&&&&&&&&&&&&&&ds.AcceptChanges();&&&&&&&&return&&&&&}}基于windows的应用程序&&&&MyTracer应用程序使用了一个tabstrip控件,以及WebBrowser&ActiveX控件以显示页面,这样来触发用户控件。当页面下载完时,该应用程序调用web&service,web&service的getinfo&方法绑定数据到tabstrip控件的tab页中。下面的代码演示了怎样结合WebBrowser的StatusTextChange及DocumentComplete事件写处理程序。//&Hook&up&the&StatusTextChange&event(订阅StatusTextChange事件)DWebBrowserEvents2_StatusTextChangeEventHandler&e1;e1&=&new&&&DWebBrowserEvents2_StatusTextChangeEventHandler(StatusTextChange);webBrowser.StatusTextChange&+=&e1;//&Hook&up&the&DocumentComplete&eventDWebBrowserEvents2_DocumentCompleteEventHandler&e2;e2_=&new&&DWebBrowserEvents2_DocumentCompleteEventHandler(DocumentComplete);webBrowser.DocumentComplete&+=&e2;&&&&在自定义的事件数据类中,它根据名字匹配处理事件,对事件有用的信息被返回。例如,类名称是DWebBrowserEvents2_DocumentCompleteEvent对应于DocumentComplete事件。&&&&所有的tab页都有一个通用的结构,都包含一个或多个datagrid控件,它们绑定到由web&service返回的dataset中的某个表中。&&&&Tracer应用程序也返回页面的view&state(如图9)。这个特性超越了asp.net默认的tracer(跟踪查看器)的功能。asp.net默认的tracer局限于只显示页面中每个控件的view&state。Mytracer&只提供显示存储在页面中的view&state元素的信息。它不包括特殊控件的view&state,就如我在msdn&杂志2003年第二期中所讲的一样,asp.net的view&state通过委托它的主页代管view&state集合。页面或控件的view&state是一个statebag对象,它通过viewstate属性暴露出来。ViewState属性是受保护的级别(protected),这使得外部的组件不能改变view&state的信息。&&&&那么用户控件是怎样返回主页的view&state呢?只有一种可能就是我也没有充分的研究映射(reflection)。从理论上来说,在公共语言运行时中的API映射允许你通过编程访问类内部的(internal)和非公共的(non-public)元素。可是,它也受级别的保护和限制,只能在asp.net应用程序的安全内容范围内进行处理。&Figure&9&&&&MyTracer运用了一个很直接但又不强的方法读页面的view&state。用户控件简单的使页面特意的暴露它的view&state给tracer工具。用户控件有一个BindViewStatey方法,被跟踪的页面能够在任何时候调用并传回它的view&state对象,如下面所示:void&Page_Load(object&sender,&EventArgs&e)&{&&&•••&&&//&Bind&the&viewstate&to&display&&&&mytracer.BindViewState(ViewState);}&&&&这样,页面也可以传递任何它拥有的view&state对象,例如,一个自定义的控件也可以在开发时输出用于调试的信息。一个简单的技巧,你可以深入的应用控件的view&state创建一个包装类专门用于暴露控件的viewstate属性。例如:public&class&MyDataGrid&:&DataGrid{&&&&public&StateBag&ExternalViewState&&&&{&&&&&&&&get&{return&ViewS}&&&&}}&&&&&然后,在页面中用一个新的控件,并绑定暴露view&state属性到mytracer应用程序。如果该控件类被密封了(声明为sealed),这个技巧就没有用了,也不能得到任何改进。所以,如果你开发了一个商业的控件不想让用户跟踪控件的状态,密封类也是一个技巧。然而,这样即有优点也有缺点。例如,我不想买第三方控件,也不想从它们哪里继承。注意,我只想简单的说说关于view&state的侦察,并不想修改它。修改view&state&实际上是不可能的(这就是它的缺点)。就如我在msdn&杂志2003年第二期专栏中所说的哪样。整合整个应用程序&&&&当你要开发和测试asp.net页面时,&mytracer是非常有用的。这个工具运行页面,捕获运行时的任何信息,然后用于友好的方式显示它们。比你用传统的方法跟踪页面,它可以提供更多的跟踪信息。这个版本的代码不支持输出自定义的信息。也不会捕获你用trace对象输出的信息。可是,增加一个message&container就向为用户控件增加一个新的write方法一样容易,message&container用于收集的所有传送过来的string对象,然后输出到另外一张表中。&&&&Mytrace可以作为一个辅助的工具,在你测试asp.net时它能代替浏览器。甚至可以把在集成在vs.net中。在你的vs.net项目配置中,在解决方案资源管理器窗口的项目名中右键,单击“属性”,选择配置“属性”,选择“调试”,选择“启动应用程序”,指定MyTracer应用程序所属的路径,并把页面的url作为该工具的命令行参数(如图10所示).Figure&10&Setting&Up&MyTracer&in&Visual&Studio&.NET&Figure&10&&&&当你应用mytracer应注意,最好不要让asp.net的调试器工作.如你需要逐步的了解的代码.没有什么比调试工具更好的了.快速监视特性允许你查看应用程序中的任何值.如果你不需要调试,&MyTracer当然也比浏览器好用.要重新允许调试,单击选择”启动应用程序”(和图10一样)。&&&&在本栏的下载源码中,你可以从源码中找到mytracer示例项目,你可以试试。下面是用户控件的源码:&%@&Control&ClassName="MyDebugTool"&Language="C#"&&AutoEventWireup="false"&%&&%@&Import&Namespace="System.Data"&%&&%@&Import&Namespace="System.Data.SqlClient"&%&&%@&Import&Namespace="System.IO"&%&&script&runat="server"&//*****************************************************************//&Run&when&the&host&page&is&unloading&and&caches&info//当主页卸载时运行,缓存信息。private&void&Page_Unload(object&sender,&EventArgs&e){&&&&GrabAndStoreContextInfo();}&&&&&&&&&&//*****************************************************************//*****************************************************************//Run&when&the&host&page&is&going&to&render//当主页呈现时运行private&void&Page_PreRender(object&sender,&EventArgs&e){&&&&GrabAndStoreRequestInfo();}&&&&&&&&&&//*****************************************************************//Key&for&the&database//数据库的主键public&string&UserKey&=&"__MyDebugTool";&&&&&//Connection&string&for&the&database//数据库连接字符串public&string&ConnString&=&"SERVER=DATABASE=MyTUID=";&&&&&&&&//Should&load&all&possible&info//是否加载所有的可能的信息public&bool&ShowAll&=&&&&&&&&&//Bind&to&the&page's&view&state&(necessary&because&viewstate&is&protected)//绑定页面的view&state(必须的,因为&viewstate受保护)private&StateBag&m_boundViewState&=&public&void&BindViewState(StateBag&state){&&&&m_boundViewState&=&}//*****************************************************************//Internals//声明dataset为内部的对象private&DataSet&info&=&new&DataSet("MyTracer");//*****************************************************************//*****************************************************************//Collect&all&the&information&from&the&HTTP&context//从http&context中收集所有的信息Application&、Session、Cacheprivate&void&GrabAndStoreContextInfo(){&&&&//Application&&&&LoadFromApplication(info);&&&&//Session&&&&LoadFromSession(info);&&&&&&&&//Cache&&&&LoadFromCache(info);&&&&//Make&the&DataSet&publicly&available&&&&PublishDataSet(info);}//*****************************************************************//*****************************************************************//Collect&all&the&request&information&from&the&HTTP&context//从http&context中收集所有请求的信息private&void&GrabAndStoreRequestInfo(){&&&&//视图&&&&LoadFromViewState(info);&&&&//控件&&&&LoadFromPageControls(info);&&&&//Form&+&QueryString&&&&LoadFromRequest(info);&&&&//Request&Headers&&&&LoadFromRequestHeaders(info);&&&&//Server&Variables&&&&LoadFromServerVariables(info);&&&&&&&&//Cookies&&&&LoadFromCookies(info);}//Load&information&from&Cache//从cache中加载信息private&void&LoadFromCache(DataSet&info){&&&&DataTable&dtCache&=&CreateKeyValueDataTable("Cache");&&&&//Page.Cashe对象为DictionaryEntry&(字典对象)结构集,该结构只有key和value两个属性&&&&foreach(DictionaryEntry&elem&in&Page.Cache)&&&&{&&&&&&&&if&(ShowAll)&&&&&&&&{&&&&&&&&&&&&AddKeyValueItemToTable(dtCache,&elem.Key.ToString(),&DisplayFormat(elem.Value));&&&&&&&&}&&&&&&&&else&&&&&&&&{&&&&&&&&&&&&&&&&string&s&=&elem.Key.ToString();&&&&&&&&&&&&if&(!s.StartsWith("ISAPIWorkerRequest")&&&&!s.StartsWith("System"))&&&&&&&&&&&&&&&&AddKeyValueItemToTable(dtCache,&elem.Key.ToString(),&DisplayFormat(elem.Value));&&&&&&&&&}&&&&}&&&&dtCache.AcceptChanges();&&&&info.Tables.Add(dtCache);&&&&}//*****************************************************************//*****************************************************************//Load&information&from&page's&controls//从页面的控件集合中加载信息(page中有两层控件集,一个htmlform及htmlform下的子控件集)private&void&LoadFromPageControls(DataSet&info){&&&&HtmlForm&theForm&=&&&&&&&&&DataTable&dtControls&=&CreateKeyValueDataTable("Controls");&&&&for&(int&i=0;&i&Page.Controls.C&i++)&&&&{&&&&&&&&//如果控件为htmlform控件,输出控件的类型,及其的ClientID&&&&&&&&if&(Page.Controls[i]&is&HtmlForm)&&&&&&&&&&&&theForm&=&(HtmlForm)&Page.Controls[i];&&&&&&&&AddKeyValueItemToTable(dtControls,&Page.Controls[i].ToString(),&&&&&&&&&&&&&Page.Controls[i].ClientID);&&&&}&&&&dtControls.AcceptChanges();&&&&info.Tables.Add(dtControls);&&&&//如果不存在htmlform控件,返回空值&&&&if&(theForm&==&null)&&&&&&&&&&&&&&&&//存在htmlform控件,输出htmlform的子控件集&&&&DataTable&dtFormControls&=&CreateKeyValueDataTable("FormControls");&&&&for&(int&i=0;&i&theForm.Controls.C&i++)&&&&&&&&AddKeyValueItemToTable(dtFormControls,&theForm.Controls[i].ToString(),&&&&&&&&&&&&&theForm.Controls[i].ClientID);&&&&dtFormControls.AcceptChanges();&&&&info.Tables.Add(dtFormControls);&&&&}//*****************************************************************//*****************************************************************//Load&information&from&Application//从application中加载信息,application对象为HttpApplicationState&类。private&void&LoadFromApplication(DataSet&info){&&&&DataTable&dtApp&=&CreateKeyValueDataTable("Application");&&&&for&(int&i=0;&i&Application.C&i++)&&&&&&&&AddKeyValueItemToTable(dtApp,&Application.Keys[i].ToString(),&&&&&&&&&&&&&DisplayFormat(Application[i]));&&&&dtApp.AcceptChanges();&&&&info.Tables.Add(dtApp);&&&&}//*****************************************************************//*****************************************************************//Load&information&from&Session//从Session中加载信息,Session对象为HttpSessionState&类。private&void&LoadFromSession(DataSet&info){&&&&DataTable&dtSession&=&CreateKeyValueDataTable("Session");&&&&for&(int&i=0;&i&Session.C&i++)&&&&&&&&AddKeyValueItemToTable(dtSession,&Session.Keys[i].ToString(),&&&&&&&&&&&&&DisplayFormat(Session[i]));&&&&dtSession.AcceptChanges();&&&&info.Tables.Add(dtSession);&&&&}//*****************************************************************//*****************************************************************//从视图中加载信息(ViewState)private&void&LoadFromViewState(DataSet&info){&&&&if&(m_boundViewState&==&null)&&&&&&&&&&&&&&&&&&&&DataTable&dtViewState&=&CreateKeyValueDataTable("ViewState");&&&&string&[]&keys&=&new&string[m_boundViewState.Count];&&&&&m_boundViewState.Keys.CopyTo(keys,&0);&&&&StateItem&[]&values&=&new&StateItem[m_boundViewState.Count];&&&&m_boundViewState.Values.CopyTo(values,&0);&&&&&&&&for&(int&i=0;&i&m_boundViewState.C&i++)&&&&{&&&&&&&&AddKeyValueItemToTable(dtViewState,&keys[i].ToString(),&&&&&&&&&&&&&DisplayFormat(values[i].Value));&&&&}&&&&dtViewState.AcceptChanges();&&&&info.Tables.Add(dtViewState);&&&&}//*****************************************************************//*****************************************************************//Load&information&from&Request.Headers//从Request.Headers中加载信息private&void&LoadFromRequestHeaders(DataSet&info){&&&&DataTable&dtHeaders&=&CreateKeyValueDataTable("Headers");&&&&for&(int&i=0;&i&Request.Headers.C&i++)&&&&&&&&AddKeyValueItemToTable(dtHeaders,&Request.Headers.Keys[i].ToString(),&&&&&&&&&&}

我要回帖

更多关于 竞彩2串1投资计划高手 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信