`

小知识(二)

阅读更多

1.关于页面的内置对象(现在先大体讲一下这些ASP.NET内置对象的本质及研究方法,关于它们的使用请看5)

以前只知道在cs里可以直接用什么Session啦Response啦Request啦Server啦Cache啦Application啦等等这些在ASP时代就已经知道的所谓的内置对象,从来没有想过这些内置对象到底是什么,直到最近在J2EE里用到了Session时却要先实例化一个Session对象才能用:HttpSession mysession=request.getSession(); 我就想为什么在ASP.NET里可以直接用呢?原来Session等在ASP.NET中被称为"内置对象",那么何为内置对象呢?其实也是类的实例,只不过这些对象的实例化比较特殊,是通过Page类的属性来实例化的(我们可以敲出Page类然后转到定义,会发现其有很多属性名就是我们的这些内置对象的名字,这些属性的get方法将实例化并返回一个这些内置对象所属类型的实例,而这个实例的引用名与内置对象名相同),这样我们在我们自己的页面里就可以直接敲出属性名(别忘了我们的页面是继承自Page类,当然可以这样做)就可以得到那些内置对象了。按照这样的逻辑只要我们知道这些内置对象所属的类型,就可以在我们页面中通过new的方式实例化这些内置对象了,我们还是以Session为例(Session.Timeout设置获取Session的过期时间默认是20分钟,Session.SessionID获取Session的唯一标识):我们敲出Session时会通过智能提示会发现内置对象Session所属类型是System.Web.SessionState命名空间里的HttpSessionState类(按照这样看来Page类所在的命名空间一定引入了System.Web.SessionState命名空间,于是敲出Page类然后转到定义,发现果然引入了System.Web.SessionState命名空间),于是就在我自己的页面也引入了System.Web.SessionState命名空间,然后用new的方式实例化了一个Session对象: HttpSessionState mysession = new HttpSessionState();然后编译...出错(System.Web.SessionState.HttpSessionState类型未定义构造函数无法实例化),于是又转到HttpSessionState的定义,发现确实没有构造函数(不过HttpSessionState类连空构造函数都没有吗?那Page类里的Session里的get方法是怎样实例化HttpSessionState类的?补:最近通过Reflector工具发现在Page类的属性里这些内置对象是通过Context对象的属性实例化的(还有种说法是这些对象是在ASP.NET页面初始化请求时自动创建的,而无需对类进行实例化操作),Context本身也是一种内置对象,其类型是HttpContext,在下面有讲解)有类似情况的还有Application,Server等,而Request和Response等虽然有构造函数,但其构造函数的参数要求都非常苛刻。那么我们只能用敲出属性名(这些内置对象的引用)的方法来获得这些内置对象的实例吗?而在J2EE中可以通过request.getSession()的方式实例化出许多HttpSession类的实例(不过个人感觉也没必要,呵呵),在JSP里可以使用Servlet中实例化的HttpSession类的引用,也可以实例化HttpSession类(但其引用不能和Servlet中相同)而Servlet中实例化的HttpSession类的引用可以相同,如在两个Servlet中都实例化了HttpSession类且引用相同,那么修改了其中一个对象也会修改另一个对象(到了这,感觉就和ASP.NET中的Session对象不同啊,每敲出Session属性就相当于实例化一个HttpSessionState类(通过Reflector工具可以看出该类实现了ICollection和IEnumerable接口,所以其是一个集合类),而该实例的引用就是Session是一个集合的引用,所以我们可以在同一个Session里添加很多键值对)。另外我们也可以在自己的页面内敲出Page属性,通过智能提示我们可以看出Page属性是所有控件的祖先Control类(到其定义中会看到很多控件的"根属性"如ID,ClientID,UniqueID等还有我们常用的FindControl方法,返回其内部控件集合的属性Controls等)的属性,通过该属性也会返回一个Page类的实例,引用名也是Page,所以根据我们前面的分析,Page也是一种内置对象。之所以我们可以敲出Page属性是因为我们的页面继承自Page类而Page类又从Control类继承,所以其实页面也是一种控件。通过Page属性得到的是Page类的实例,而通过this关键字得到的是当前页面类的实例,所以this包含的东西>=Page包含的东西

 

2.之所以写1是因为在http://kendezhu.iteye.com/blog/745538里用到了Context这个内置对象,当时是通过httpcontext.current获得的这个内置对象,那么现在让我们来简单看一下Context(http上下文类HttpContext的实例):

http://msdn.microsoft.com/zh-cn/library/system.web.httpcontext(v=VS.80).aspx

 

1.Context.Handler(获得"传送页"的实例的引用(而且是传送页的aspx页面类的实例引用:http://kendezhu.iteye.com/blog/788770),类似于http://kendezhu.iteye.com/blog/748769的17补)(注意:Context.Handler只能通过在"传送页"使用Server.Transfer("接收页"),才能在接收页得到传送页的实例引用,而PreviousPage既能Server.Transfer("接收页")又能PostBackUrl)

http://www.cnblogs.com/suchenge/articles/1530142.html

传送页 D.aspx cs:

public partial class D : System.Web.UI.Page

    {

        private string s = "我来自D";

        public string S

        {

            get { return s; }

            set { s = value; }

        }

 

        protected void Button1_Click(object sender, EventArgs e)

        {

            Server.Transfer("C.aspx");

        }

    }

接收页 C.aspx cs:

 public partial class C : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

  关于is和as:http://blog.csdn.net/kendezhu/archive/2009/12/07/4959312.aspx

Context.Handler的方式只能用Server.Transfer()         

            if (Context.Handler is D)

            {

要知道Context.Handler实质上就是ASP.D_aspx类,其继承自D(http://kendezhu.iteye.com/blog/788770)所以能够进行强制转换

                  D d = (D)Context.Handler;

                Label1.Text = ((TextBox)d.FindControl("TextBox1")).Text + d.S;

            }

        }

    }

如果有多个传送页,比如还有一个B.aspx,可以在接收页里根据不同的传输页进行不同的操作(这里用is判断是可以的,因为不同的页面是不能强制转换的,基类页与派生页是可以进行强制转换的,也就是is将返回true),而对于PreviousPage也可以在接收页里根据不同的传输页进行不同的操作:

 

context.handler接收页:

 public partial class C : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            if (Context.Handler is B)

            {

                B b = (B)Context.Handler;

                Label1.Text = ((TextBox)b.FindControl("TextBox1")).Text + b.S;

            }

            if (Context.Handler is D)

            {

                  D d = (D)Context.Handler;

                Label1.Text = ((Label)d.FindControl("Label1")).Text;

            }

        }

    }

PreviousPage接收页:

 

   public partial class G : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

PreviousPage的方式可以用Server.Transfer(),也可以用PostBackUrl

            if (PreviousPage is E)

            {

要知道Previous实质上就是ASP.E_aspx类,其继承自E(http://kendezhu.iteye.com/blog/788770)所以能够进行强制转换

                Label1.Text = ((TextBox)PreviousPage.FindControl("TextBox1")).Text + ((E)PreviousPage).S;

            }

            if (PreviousPage is F)

            {

                Label1.Text =((Label)PreviousPage.FindControl("Label1")).Text;

            }

        }

    }

 

2.Context.RewritePath

http://www.cnblogs.com/zhchongyao/archive/2009/10/21.html

单独写貌似没有用:Context.RewritePath("Rewirtepath.aspx?w=23");

这样写:

Context.RewritePath("Rewirtepath.aspx?w=23");

Server.Transfer("Rewirtepath.aspx);

效果上等于:Server.Transfer("Rewirtepath.aspx?w=23");

 

3.Context.Items(可以起到页面间传值的作用)

http://www.cnblogs.com/barney/archive/2008/07/19/1246626.html

比Session功能要弱一些(主要体现在Context.Items在做转页时必须用Server.Transfer,否则在接收页得不到值):

 

 public class Class1

    {

        public string name;

        public int age;

    }

传送页 cs:

 

 protected void Page_Load(object sender, EventArgs e)

        {

            Class1 c = new Class1();

            c.name = "小刘";

            c.age = 20;

            Context.Items["person"] = c;

            Server.Transfer("接收页");

           //Response.Redirect("接收页");  用Session的话是可以的

        }

接收页 cs:

 

protected void Page_Load(object sender, EventArgs e)

        {

            if (Context.Items["person"] != null)

            {

  关于is和as:http://blog.csdn.net/kendezhu/archive/2009/12/07/4959312.aspx

                Class1 c = Context.Items["person"] as Class1;

  也可直接粗鲁地强制转换 Class1 c =(Class1)Context.Items["person"];

                Label1.Text = c.name + " " + c.age.ToString();

            }

        }

值得一提的是也有Items这种内置对象,但却实现不了这种效果,必须要写Context.Items["*"]才可以。

 

3.动态添加控件:http://www.cnblogs.com/ringwang/archive/2008/05/07/1187213.html

http://www.cnblogs.com/lovecherry/archive/2005/04/16/138968.html

http://www.cnblogs.com/chenxizhang/archive/2009/05/19/1460544.html

http://www.cnblogs.com/blusehuang/archive/2007/04/26/728079.html(动态添加控件ID一定要不同)

http://kendezhu.iteye.com/admin/blogs/690772

这种添加的自然是各种服务器端控件了,样式设置可以直接在生成控件时设置也可以后来通过CSS来设置,不过关于定位问题,最好将生成的控件添加在容器控件里(如Panel,Table等),这样我们只要给这些容器控件定位就可以了。

关于网上很多人说在回发后这些控件不见了,原因可能有两点1.写在Page_Load()里面的!IsPostBack(只有第一次请求才进行)里了(IsPostBack自然是第一次不进行,回发时才进行)2.写在控件事件里了(回发后你没有触发该事件自然不会处理了)

还有一点很重要,在动态添加控件时要注意控件的ID一定要不同,因为服务器端与浏览器端对控件的状态(包括最重要的控件的属性值)的来回交流靠的就是viewstate(可禁)和控件状态(不可禁),而viewstate和控件状态就是根据不同控件ID及其不同属性等来分发数据的。当然只有服务器的控件的状态可以在回发后被保存(一个TextBox一个<input type="text">都被设值,回发后TextBox的值还会在),不过客户端控件也有办法:http://www.cnblogs.com/Randy0528/archive/2007/01/07/614368.html (保存客户端控件的状态的方法(以textarea为例))

关于ViewState和控件状态:http://book.51cto.com/art/200902/109016.htm

http://www.cnblogs.com/chenxizhang/archive/2009/04/02/1427827.html

http://kendezhu.iteye.com/admin/blogs/752240里的

还可以直接用Response.Wirte(客户端控件)直接往页面上输出,然后用CSS设置样式(当然这种仅限客户端控件,而且定位也要靠CSS,当然对于样式和定位的设置你也可以写在Response.Wirte里,但这样会使代码看起来很乱)

 

4.一个页面使用多个表单分别提交到不同的页面

<body>

    <form id="form1" runat="server" style="border:solid 1px yellow; margin-bottom:3px;">

        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

        <input type="text" name="username" />

        <asp:Button ID="Button1" runat="server" Text="表单1" PostBackUrl="B.aspx" />

    </form>

    <form id="form2" action="C.aspx" style="border:solid 1px yellow;" method="post">

    <input type="text" name="username" />

    <input type="password" name="password" />

     <input type="submit" name="tijiao" value="表单2"/>

    </form>

</body>

值得注意的是ASP.NET中一个页面中只能有一个表单有runat="server",其他表单由于没有runat="server"所以将不能使用大部分服务器端控件。 这里B.aspx只能得到form1中的值    C.aspx只能得到form2中的值。

 

5.ASP.NET一些常用内置对象的使用

用来存储信息(一般都是集合类型的内置对象):Session(HttpSessionState) Application(HttpApplicationState) Cache(Cache) 更多请参考这里Cookies的使用

其他非集合类的内置对象的使用

 

6.数据库的每一张表中只能有一个标识字段。

 

7.将指定字符串按指定长度进行剪切

        <param   name= "oldStr "> 需要截断的字符串 </param> 

        <param   name= "maxLength "> 字符串的最大长度 </param> 

        <param   name= "endWith "> 超过长度的后缀 </param> 

        <returns> 如果超过长度,返回截断后的新字符串加上后缀,否则,返回原字符串 </returns> 

        public static string StringTruncat(string oldStr, int maxLength, string endWith)

        {

            if (string.IsNullOrEmpty(oldStr))

                //   throw   new   NullReferenceException( "原字符串不能为空 "); 

                return oldStr + endWith;

            if (maxLength < 1)

                throw new Exception("返回的字符串长度必须大于[0] ");

            if (oldStr.Length > maxLength)

            {

                string strTmp = oldStr.Substring(0, maxLength);

                if (string.IsNullOrEmpty(endWith))

                    return strTmp;

                else

                    return strTmp + endWith;

            }

            return oldStr;

        }

注意:如果前台绑定时用到此函数<%# StringTruncat(Eval("title").ToString(),30,"...")%>,因为Eval()返回Object

http://qun.51.com/xinchaoliu/topic.php?pid=456

 

8.CSS 伪类与伪对象  具体参考CSS手册

 

9.JavaScript里的this    ②

 

10. JavaScript内置函数和JavaScript 对象   ②  (本地对象,就是那些官方定义好了的类的对象。内置对象是本地对象的一种,其只包含Global对象和Math对象等。而宿主对象则是那些官方未定义,你自己构建的对象加上DOM和BOM对象组成的。 )

要使用相应的JavaScript对象才能使用相应的JavaScript内置函数。具体参考JavaScript参考手册

 

11.图片放大镜效果

CSS:

 

 <style type="text/css">

    #smallImgCon {position:relative;left:0;top:0;}

#magnifierCon {height:276px;width:276px;position:absolute;overflow:hidden;z-index:3}

#magnifierCon img#magnifierBg {position:absolute;z-index:2}

#magnifierCon img#largeImg {position:absolute;z-index:1}

    </style>

HTML:

 

 <div onmousemove="imgZoomOut(event)" id="smallImgCon"> 
		<img alt="" src="images/smallimg.jpg" id="smallImg"/>	
		<div id="magnifierCon" style="display:none"> 
			<img alt="" src="images/magnifier.png" id="magnifierBg"/> 
			<img alt="" src="images/largeimg.jpg" id="largeImg"/>	
		</div> 
	</div> 

 JavaScript:

 

<script type="text/javascript">
	var smallImgCon = document.getElementById("smallImgCon");
	var smallImg = document.getElementById("smallImg");
	var magnifierCon = document.getElementById("magnifierCon");
	var magnifierBg = document.getElementById("magnifierBg");
	var largeImg = document.getElementById("largeImg");
	
	function getImageSize(imageEl) {
		var i = new Image();
		i.src = imageEl.src;
		return new Array(i.width, i.height);
	}
	
	function imgZoomOut(event) {
		magnifierCon.style.display = "block";
		smallImgConLocationX = smallImgCon.offsetLeft;//得到小图片X坐标
		smallImgConLocationY = smallImgCon.offsetTop;//得到小图片Y坐标
		
		x = event.clientX - smallImgConLocationX;//光标相对小图片左上角X坐标
		y = event.clientY - smallImgConLocationY;//光标相对小图片左上角Y坐标
		
		var smallSize = getImageSize(smallImg);
		smallImgWidth = smallSize[0];
		smallImgHeight = smallSize[1];
		
		var largeSize = getImageSize(largeImg);
		largeImgWidth = largeSize[0];
		largeImgHeight = largeSize[1];
		
		var magnifierSize = getImageSize(magnifierBg);
		magnifierWidth = magnifierSize[0];
		magnifierHeight = magnifierSize[1];
		
		
		if ( x < 0 || x > smallImgWidth || y < 0 || y > smallImgHeight) {
			dispear();
		}else {
			magnifierCon.style.left = x - magnifierWidth/2 + "px";//放大镜X坐标
			magnifierCon.style.top = y - magnifierHeight/2 + "px";//放大镜Y坐标
		
			x = - x*(largeImgWidth/smallImgWidth) + magnifierWidth/2;
			y = - y*(largeImgWidth/smallImgWidth) + magnifierHeight/2;
						
			largeImg.style.left = x + "px";
			largeImg.style.top = y + "px";
		
		}
		
	}
	function dispear() {
		magnifierCon.style.display = "none";
	}
	</script>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics