一:ASP.NET中缓存分类,共3种
页面输出缓存、页面片段缓存、页面数据缓存
二:页面输出缓存
      可以使用页面输出缓存来提高WEB站点的性能。可以缓存页面的输出并且把缓存起来的拷贝发送出去以响应浏览器的请求,而不是每次在请求页面时执行页面
     例:你的站点包括一个从数据库表检索出来的显示产品信息的页面。默认情况下,每次用户访问产品页面时,都必须执行该页面并且从数据库检索数据。但如果启用页面输出缓存,这个页面就只执行一次,并且只从数据库检索一次数据。这就意味着减轻了WEB应用程序和数据库服务器的负载。
     要启用页面输出缓存,在页面中包括如下页面处理指令即可:
<%@ OutputCache Duration="60" VaryByParam="none" %>
如下例:
<%@ Page Language="C#" %>
<%@ OutputCache Duration="300" VaryByParam="none" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script language="C#" runat="server">
void Page_Load(Object sender , EventArgs e)
{
SqlConnection conNorthwind;
string strSelect;
SqlCommand cmdSelect;
SqlDataReader dtrProducts;
conNorthwind = new SqlConnection( @"Server=localhost;Integrated Security=SSPI;Database=Northwind" );
strSelect = "Select * From Products Where ProductID=1";
cmdSelect = new SqlCommand( strSelect, conNorthwind );
conNorthwind.Open();
dgrdProducts.DataSource = cmdSelect.ExecuteReader( CommandBehavior.SingleRow );
dgrdProducts.DataBind();
conNorthwind.Close();
string strTime = DateTime.Now.ToString();
lblMessage.Text = strTime;
}
</script>
<html>
<head><title>ProductPage.aspx</title></head>
<body>
<asp:DataGrid
ID="dgrdProducts"
CellPadding="10"
Runat="Server" />
<hr>
<small>Last Updated: <asp:Label
ID="lblMessage"
Font-Bold="True"
ForeColor="Blue"
Runat="Server" /></small>
</body>
</html>
此例中显示了从Northwind数据库检索到的特定产品信息,这个页面被缓存5分钟。
注:不能保证缓存的项总会保留在页面的输出缓存中。如果系统资源不足,ASP.NET框架会开始从缓存中清理缓存项。
属性Duration表示缓存的时间,以秒为单位。
属性VaryByParam表示对一个页面请求中包含参数(查询字符串参数或表单域参数)时页面该如何被缓存。这个属性可以接受分号作为分隔符的参数列表,或者是如下两个特殊值:
none------表示即使页面被请求时带不同的参数,也不会创建页面不同的缓存版本。
*-----------表示在页面被请求时带有不同的参数,则创建页面不同的缓存本。
      <%@ OutputCache Duration="300" VaryByParam="pid" %>
这条指令根据查询字符串参数pid


 

设置缓存的位置---属性Location(取来自OutputCacheLocation枚举类型的一个值)
Any---默认值。页面可在任何地方缓存,包括服务器、下游服务器、浏览器。
Client---页面的输出只在浏览器缓存。
DownStream----页面的输出只在下游服务器上缓存。
None----不执行页面缓存操作。
Server----页面只在服务器端缓存。
使用HttpCachePolicy--精确控制页面的缓存行为
其中SetExpires()方法表示页面过期的日期,SetCacheability()方法表示页面要如何来缓存。SetCachability()方法取HttpCacheability枚举类型中的值:
NoCache---防止任何页面用Cache-Control:no-cache头来缓存。
Private--表示页面不应当被代理服务器来缓存,但可以被浏览器缓存。默认值。
Public--表示页面可以被浏览器和代理服务器缓存。
Server--表示页面只可以在服务器端被缓存。
三:使用页面片段缓存
页面片段缓存是通过用户服务控件来实现的。通过为页面的每个区域创建一个单独的用户控件,就可以定义页面的不同区域。在每个用户控件中,可以使用OutputCache指令来表示如何缓存控件的输出。
注意:
在默认情况下,每个用户控件的输出都被单独缓存起来,如果要跨多个用户控件共享同样的输出缓存,以节省内在开销,那么可以使用Shared属性
<%@ OutputCache Duration="60" VaryByParam="*" Shared="true" %>
页面片段缓存的限制:
由于控件被缓存了,就不能在页面中编程设置用户控件的属性;也不能对被缓存的用户控件使用数据绑定的语法。
四:使用页面数据缓存
每个ASP.NET应用程序都有一个Cache对象,直到应用程序重新启动之前该对象一直可用。
        Cache.Insert("t1", "goodtyl");//新增项
        Cache.Insert("t2", "weiwei");
        Cache.Insert("t3", "haha");
        Cache.Remove("t3");//移除项
        //遍历Cache,注意System.Collections.DictionaryEntry:定义可设置或可检索的字典键/值对
        foreach(DictionaryEntry temp in Cache)
        {
            Response.Write("key: " + temp.Key.ToString() + "value: " + temp.Value.ToString() + "<br>");
        }
添加缓存文件依赖:在添加一个文件依赖时,可以把该项与一个文件相关联。如果文件发生改变,就自动从缓存中删除该项。如例:Cache.Insert("mi","hello",new System.Web.Caching.CacheDependency(MapPath("a.txt")));如果a.txt被修改了,那么,mi就自动从缓存中删除。
添加缓存触发依赖:只要数据库表的记录发生改变就更新缓存中的一项。
需要使用sqlserver触发器及xp_cmdshell扩展存储过程。
CREATE TRIGGER UpdateCache
ON Products
FOR UPDATE, DELETE, INSERT
AS
DECLARE @cmd Varchar( 200 )
SELECT @cmd = 'echo ' + Cast( getDATE() As Varchar( 50 ) ) +
' > c:\tableChange.txt'
EXEC master..xp_cmdshell @cmd, no_output
代码:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script language="C#" runat="server">
void Page_Load(Object sender , EventArgs e)
{
DataSet dstProducts = (DataSet)(Cache[ "productsDS" ]);
if ( dstProducts == null )
{
    dstProducts = GetProducts();
    Cache.Insert( "Products", dstProducts, new CacheDependency( "c:\\tableChange.txt" ) );
}
dgrdProducts.DataSource = dstProducts;
dgrdProducts.DataBind();
}
DataSet GetProducts() {
   SqlConnection conNorthwind;
   string strSelect;
   SqlDataAdapter dadProducts;
   DataSet dstProducts;
conNorthwind = new SqlConnection( @"Server=localhost;Integrated Security=SSPI;Database=Northwind" );
strSelect = "Select TOP 20 * From Products ORDER BY ProductID";
dadProducts = new SqlDataAdapter( strSelect, conNorthwind );
dstProducts = new DataSet();
dadProducts.Fill( dstProducts, "ProductsDS" );
return dstProducts;
}
</script>
<html>
<head><title>DatabaseDependency.aspx</title>
</head>
<body>
<asp:DataGrid
ID="dgrdProducts"
Runat="Server" />
</body>
</html>
添加缓存键依赖
<%@ Page Language="C#" %>
<script language="C#" runat="server">
void UpdateItem1( object s, EventArgs e )
{
Cache[ "item1" ] = txtNewValue.Text;
}
void UpdateItem2( object s, EventArgs e )
{
   string arrKeyDepends = ( "item1" );
   Cache.Insert( "item2", txtNewValue.Text, new CacheDependency( Server.MapPath(arrKeyDepends), System.DateTime.Now ) );
}
</script>
<html>
<head><title>KeyDependency.aspx</title></head>
<body>
<form Runat="Server">
<asp:TextBox
ID="txtNewValue"
Runat="Server" />
<p>
<asp:Button
Text="Update Item1"
OnClick="UpdateItem1"
Runat="Server" />
<asp:Button
Text="Update Item2"
OnClick="UpdateItem2"
Runat="Server" />
<hr>
Item1 = <%=Cache[ "item1" ]%>
<br>
Item2 = <%=Cache[ "item2" ]%>
</form>
</body>
</html>
创建一个绝对过期策略
Cache.Insert("Time", strTime, null, DateTime.Now.AddMinutes( 1 ), Cache.NoSlidingExpiration );
创建相对过期策略
Cache.Insert("Time", strTime, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes( 1 ) );
设置缓存项的优先级
Cache.Insert("my","hello",null,Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration,CacheItemPriority.High,null);
创建缓存回调方法:在插入一个项到缓存时,可以把一个回调方法与这个项关联起来。无论是何种原因,只要该项从缓存中删除,那么回调方法就自动执行。
最明显的回调应用是当一个项过期时自动把该项重新加载到缓存中。
示例代码:
<%@ Page Language="C#" %>
<script language="C#" runat="server">
public static CacheItemRemovedCallback onRemove;
//CacheItemRemovedReason
表示从缓存中删除项的原因
void ItemRemoved( string strItemKey, object objItemValue, CacheItemRemovedReason objRemovedReason )
{
string strLogEntry;
strLogEntry = "Item with value " + objItemValue.ToString() ;
strLogEntry = " removed at " + System.DateTime.Now.ToString( "T" );
strLogEntry = " because of " + objRemovedReason.ToString();
if ( Application[ "CacheLog" ] == null )
{
   Application[ "CacheLog" ] = new ArrayList();
}
//Application[ "CacheLog" ].Add( "strLogEntry" );
//Beep();
}
void btnAddCache_Click( object s, EventArgs e )
{
onRemove = new CacheItemRemovedCallback( ItemRemoved );
    Cache.Insert( "myItem", txtNewValue.Text, null, DateTime.Now.AddSeconds( 10 ), Cache.NoSlidingExpiration, CacheItemPriority.High, onRemove );
}
void btnRemoveCache_Click( object s, EventArgs e )
{
Cache.Remove( "myItem" );
}
void Page_PreRender( object s, EventArgs e )
{
dgrdCacheLog.DataSource = Application[ "CacheLog" ];
dgrdCacheLog.DataBind();
}

</script>
<html>
<head><title>CacheCallback.aspx</title></head>
<body>
<form Runat="Server">
<h2>Cache Log</h2>
<asp:DataGrid
ID="dgrdCacheLog"
CellPadding="8"
Runat="Server" />
<p>
<asp:TextBox
id="txtNewValue"
Runat="Server" />
<p>
<asp:Button
id="btnAddCache"
Text="Add To Cache!"
OnClick="btnAddCache_Click"
Runat="Server" />
<asp:Button
id="btnRemoveCache"
Text="Remove From Cache!"
OnClick="btnRemoveCache_Click"
Runat="Server" />
<asp:Button
Text="Refresh Page!"
Runat="Server" />
</form>
</body>
</html>

 

posted @ 2009-10-25 14:52 MYGIS_3 阅读(21) 评论(0) 编辑
      事务是实现原子性的手段,原子性是指某些事情要么全部发生,要么都不发生,程序的执行是有顺序的,在程序的执行过程中,难免会出现错误,遇到突发事件,如电脑死机了,停电了等,如果对于某些必须作为原子性事务发生的事,在执行过程中,有一部执行了,还有另外一部分由于某种错误而没有执行,就会出现大麻烦。因此当某部分程序出现错误时需要执行该事务的回滚。

  测试:

  1.SQL查询分析器:

  i. create table MyTransactionTest
 (
   userId int primary key identity
 )

 

ii.

begin transaction  TranStart

insert into  MyTransactionTest default values
save transaction firstTransaction

 

insert into  MyTransactionTest default values
rollback transaction firstTransaction

 

insert into  MyTransactionTest default values
save transaction secondTransaction

 

insert into  MyTransactionTest default values
rollback transaction secondTransaction

 

insert into  MyTransactionTest default values
commit transaction TranStart

 

iii.

select * from MyTransactionTest

 

结果:

图片

 

2.VS2005

 

SqlConnection con = new SqlConnection("server=(local);DataBase=db;User ID=sa;PWD=");
con.Open();
SqlTransaction st = con.BeginTransaction();//通过SqlConnection的BeginTransaction方法创建名为st的对象Transaction
SqlCommand com = con.CreateCommand();
com.Transaction = st;//将SqlTransaction对象分配给SqlCommand对象的Transaction属性
try
 {       
                com.CommandText = "";     // 省略, 关于数据表的操作
                com.ExecuteNonQuery();
                //向日志表中插入数据
                com.CommandText = "";//   省略

                com.ExecuteNonQuery();
                st.Commit();//提交事物
                Response.Write("<script>alert('注册成功!');location='javascript:history.go(-1)'</script>");
     }
catch (Exception error)
    {
         st.Rollback();//回滚事物
    }

posted @ 2009-09-29 09:03 MYGIS_3 阅读(9) 评论(0) 编辑

图片

修正:

图片

posted @ 2009-09-29 09:01 MYGIS_3 阅读(135) 评论(0) 编辑

using System;
using System.IO;

public class Test
{
    public static void Main()
    {
        int i = 42;
        object o = i;

        Console.Write(i + "." + (Int32)o);
        Console.ReadLine();
    }
}

请问以上代码发生了几个装箱拆箱操作?
发生了三个装箱操作、一个拆箱操作,
装箱1:int i = 42;
装箱2:Console.Write()中的第一个参数i,需要由值类型(i)装箱为引用类型,以便于这个方法的原型一致。
拆箱1:(Int32)o;
装箱3:(Int32)o拆箱完成后需要再装箱。

posted @ 2009-09-29 08:41 MYGIS_3 阅读(40) 评论(0) 编辑

转自:http://hi.baidu.com/wwp0726/blog/item/4a6dc01750e576094b90a767.html

innerText,outerText,innerHTML,outerHTML
这次我们要使用另一些对象属性对来实现动态改变文本,它们就是:innerText,outerText,innerHTML,outerHTML,千万要注意它们的大小写,因为错一点您就得不到预期的效果了。这是全新的方法,当您掌握它以后将可随心所欲的设计动态内容了,不可错过哦!
例12 动态改变文本和Html
<html>
<head>
<title>DHtml举例12</title>
<style><!--
body {font-family:"宋体";color="blue";font-size="9pt"}
-->
</style>
<script language="JavaScript">
function changeText()
{
DT.innerText="我很好!";
}//function

function changeHtml()
{
DH.innerHTML="<i><u>我姓肖!</u></i>";
}//function

function back()
{
DT.innerText="您好吗?";
DH.innerHTML="您姓什么?";
}
</script>
</head>

<body>
<p><font color="gray">请点击下边的文字……</font>
<ul>
<li id="DT" onclick="changeText()">您好吗? </li>
<li id="DH" onclick="changeHtml()">您姓什么? </li>
<li onclick="back()">恢复原样! </li>
</ul>
</body>
</html>

innerText属性用来定义对象所要输出的文本,在本例中innerText把对象DT中的文本“您好吗?”变成了“我很好!”(语句DT.innerText="我很好!")。而对对象DH的改变用了innerHTML属性,它除了有innerText的作用外,还可改变对象DH内部的HTML语句,于是它把文本变成了“我姓肖!”,而且文本输出改成了斜体(<i></i>)并下加一条直线(<u></u>),即语句DH.innerHTML="<i><u>我姓肖!</u></i>"。outerText和outerHTML也具有类似的作用,读者不妨自己试试看。


下面我们来设计一个有趣的动态页面。

例13 文本的动态输入与输出
<html>
<head>
<title>DHtml举例13</title>
<style><!--
body {font-family:"宋体";color="blue";font-size:"9pt"}
.blue {color:blue;font-size:9pt}
-->
</style>
<script language="JavaScript">
function OutputText()
{
if(frm.txt.text!="")
{ Output.innerHTML="在此处输出文本:<u>"+frm.txt.value+"</u>";} //Output为一对象。
else
{ Output.innerText="在此处输出文本:";}
}//function

</script>
</head>

<body>
<p><br></p>

<form name="frm">
<p><font color="gray">请在文本框中输入文字:</font>
<input type="text" name="txt" size="50"><br>
<input type="button" value="输出文本" name="B1" class="blue" onclick="OutputText()"></p>
</form>

<p id="Output">在此处输出文本:</p>
</body>
</html>

此例的动态效果如下,先在文本框中输入文本,然后按“输出文本”的按钮,接着网页便会自动输出您所输入的文本。



此外,我们还可使用insertAdjacentHTML和insertAdjacentText方法(方法即是某特定对象能直接调用的函数)在先前文本或Html内容的前边或后边插入新的文本或Html内容,使用这些方法需要参数,这些参数有:BeforeBegin、 AfterBegin、 BeforeEnd和AfterEnd,它们是用来标明文本或Html插入的地方。具体用法如下例:

例14 使用insertAdjacentHTML插入文本
<html>
<head>
<title>DHtml举例14</title>
<style><!--
body {font-family:"宋体";color="blue";font-size:"9pt"}
-->
</style>
<script language="JavaScript">
function Insert()
{
document.all.New.insertAdjacentHTML("AfterBegin","<font color=red>-新插入的内容-<font>");
//第一个参数是用来指明位置,第二个参数是要插入的Html内容。
}//function
</script>
</head>
<body>
<p><br>
</p>
<p id="New" onclick="Insert()">点击此行蓝色文字将插入文本</p>
</body>
</html>
posted @ 2009-09-23 11:08 MYGIS_3 阅读(39) 评论(0) 编辑

转自:http://www.cnblogs.com/reonlyrun/archive/2007/03/30/693188.html

在 ASP.NET 的开发中 Web 用户控件的开发和使用是一项必不可少的技术,在对这项技术的一番研究后写下了这篇随笔,不过确实担心这么初级的东东放到原创首页上会被拍砖头。

1.简介
2.创建 Web 用户控件
3.在 Web 窗体中使用 Web 用户控件
4.添加属性
5.添加方法
6.添加自定义事件
7.控件内客户端角本访问服务器控件的方法
8.代码下载


1.简介
    当 ASP.NET 内置的 Web 服务器控件不能满足我们开发的需要时,通过我们会创建自己的控件。而在 ASP.NET 中有两个选择:

    1)用户控件:用户控件是能够在其中放置标记和 Web 服务器控件的容器。然后,可以将用户控件作为一个单元对待,为其定义属性和方法。(这就是咱们这次要讲的啦)
    2)自定义控件:自定义控件是编写的一个类,此类从 Control 或 WebControl 派生。(关于这个方面的技术,目前为止我只按MSDN的演练做了一个练习,后面有时间针对它的开发与使用再写一篇更详细一点的)

    创建用户控件要比创建自定义控件方便很多,因为可以重用现有的控件,所以最适合创建具有复杂界面元素的控件。用户控件与 Web 窗体(.aspx)很相似,可以同时具有前台页面和后台代码,在前台可以向其中添加所需的标签和服务器控件,在后台可以针对这些对象进行逻辑操作。不过它们存在以下这些区别:

    1)用户控件的文件扩展名为 .ascx,而 Web 窗体的扩展名为 .aspx;
    2)用户控件使用 @Control 指令声明,而 Web 窗体使用 @Page 指令;
    3)用户控件不能作为独立文件运行,而必须其它服务器控件一样,将它们添加到 Web 窗体中;
    4)用户控件中不能包含 <html>、<body> 和 <body> 等标签。

2.创建 Web 用户控件

首先建立一个 ASP.NET 网站,如图所示:


在解决方案资源管理器里选中网站,点击右键菜单中的[添加新项],在弹出窗口选择 Web 用户控件,如图所示


点击[添加],在解决方案中可以看到一个新的 Web 用户控件做好了,如图所示:


什么?什么?这就做好了?呵呵,做是做好了,不过没什么功能,现在我们给它加点东西。
编辑TestWebUserControl.ascx,切换到[设计]视图,从工具箱拖动一个 TextBox、一个 Button 和一个 Label 控件到页面上,如图所示:


选中 Button 控件,双击,为其添加 Click 事件的响应代码:
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text 
= TextBox1.Text;
    }

OK!到此为止,一个简单的 Web 用户控件搞定了。

3.在 Web 窗体中使用 Web 用户控件

现在我们把做好的用户控件放到窗体上进行测试,选中 Default.aspx 切换到[设计]视图(注意:一定要在设计视图里),在解决方案中拖动 TestWebUserControl.ascx 到页面上,如图所示:


现在我们运行程序,在文本框中填入“Hello World!”,点击 Button ,Label 就会显示相应内容了,如图所示:


停止程序,回到 Default.aspx 的[源]视图,我们来看看刚才的“一拖”,IDE到底为我们做了什么工作。可以发现在代码里增加了一行 @Register 指令,这就是对用户控件引用要做的声明,代码如下:
<%@ Register Src="TestWebUserControl.ascx" TagName="TestWebUserControl" TagPrefix="uc1" %>

这个指令很简单,通过字面就可以看出各属性的含义了。现在我们为了使我们的控件前缀更有意义,而不是什么“uc1”之类的,对这条语句做点修改,代码如下:
<%@ Register Src="TestWebUserControl.ascx" TagName="TestWebUserControl" TagPrefix="Clark" %>

当然,相应的其它地方也要进行修改了,如下:

<uc1:TestWebUserControl ID="TestWebUserControl1" runat="server" />
改为
<Clark:TestWebUserControl ID="TestWebUserControl1" runat="server" />

这样,以后我们再在页面使用 TestWebUserControl 控件时前缀自动就变成Clark了,如下所示,我又拖了一个控件到页面里,代码如下:
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Src="TestWebUserControl.ascx" TagName="TestWebUserControl" TagPrefix="Clark" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>无标题页</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<Clark:TestWebUserControl ID="TestWebUserControl1" runat="server" />
        
<br />
        
<Clark:TestWebUserControl ID="TestWebUserControl2" runat="server" />
    
</div>
    
</form>
</body>
</html>

当然,通过在 Web.Config 里进行配置也可以注册组件,并且是针对整个网站适用的,这里就不再述。

4.添加属性

下面我们来为做好的控件添加一个属性,添个什么好呢?(本人最大的弱点就是不会写例子。。。)随便来一个吧,编辑 TestWebUserControl.ascx.cs 添加如下代码:
    public string LabelContext
    {
        
get { return Label1.Text; }
        
set { Label1.Text = value; }
    }

这样一个可读写的文本属性就做好,太简单了。。。

选中 Default.aspx 切换到[设计]视图,分别选中两个用户控件,在属性查看器里对 LabelContext 进行设置,如图所示:


为了测试该属性的实现,我们再在 Default.aspx 的页面上添加一个 Button 控件,对其 Click 事件添加响应代码,如下:
    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.Write(TestWebUserControl1.LabelContext + " " + TestWebUserControl2.LabelContext);

    }

运行程序,点击该按钮,效果如图所示:


5.添加方法

属性加好了,现在再添加一个方法,编辑 TestWebUserControl.ascx.cs ,添加如下代码:
    public void ChangeLabelContext(object sender, string value)
    {
        Label1.Text 
= value;
    }

大家可能注意到,我这个方法有一个 sender ,这是干什么用的呢?别着急,在后面添加事件里会讲到的。

为了测试这个方法,选中 Default.aspx ,切换到[设计]视图,再添加一个按钮,为其 Click 事件添加如下的响应代码:
    protected void Button2_Click(object sender, EventArgs e)
    {
        TestWebUserControl1.ChangeLabelContext(sender, 
"Hi");
        TestWebUserControl2.ChangeLabelContext(sender, 
"cnblogs");
    }

现在运行程序,点击该按钮,效果如图所示:


6.添加自定义事件

属性和方法我们做好了,那么事件呢?
继续编辑 WebUserControlTest.ascx.cs ,首先定义一个代理,代码如下:
public delegate void LabelContextChangedHandler(object sender, LabelContextChangedEventArgs e);

public class LabelContextChangedEventArgs : EventArgs
{
    
private string labelContext;

    
public LabelContextChangedEventArgs(string value)
    {
        labelContext 
= value;
    }
    
public string LabelContext
    {
        
get { return labelContext; }
    }
}

再为 TestWebUserControl 这个类添加一个事件变量和事件触发函数,代码如下:
    public event LabelContextChangedHandler LabelContextChanged;

    
private void OnLabelContextChanged(object sender, LabelContextChangedEventArgs e)
    {
        
if (LabelContextChanged != null)
        {
            LabelContextChanged(sender, e);
        }
    }

然后,在 ChangeLabelContext 函数里增加对事件的触发,需要修改原来的代码,如下:

    public void ChangeLabelContext(object sender, string value)
    {
        Label1.Text 
= value;
    }
改为
    public void ChangeLabelContext(object sender, string value)
    {
        Label1.Text 
= value;
        OnLabelContextChanged(sender, 
new LabelContextChangedEventArgs(value));
    }

OK!到此,我们就完成了对用户控件事件的定义并确定了在何时触发这个事件,下面我们来测试一下。

编辑Default.aspx.cs,先添加一个响应事件的函数,代码如下:
    private void TestWebUserControl_LabelContextChanged(object sender, LabelContextChangedEventArgs e)
    {
        Button tmpButton 
= (Button)sender;
        
if (tmpButton.Text == "Button")
        {
            tmpButton.Text 
= e.LabelContext;
        }
        
else
        {
            tmpButton.Text 
+= " " + e.LabelContext;
        }
    }
实现的效果就是将触发事件的 Button 控件的 Text 属性设置成用户控件 LabelContext 的值。

现在,再在页面的 Page_Load 事件的响应代码里将两个用户近件的 LabelContextChanged 和 这个函数“连接”起来就OK啦!代码如下:
    protected void Page_Load(object sender, EventArgs e)
    {
        TestWebUserControl1.LabelContextChanged 
+= new LabelContextChangedHandler(TestWebUserControl_LabelContextChanged);
        TestWebUserControl2.LabelContextChanged 
+= new LabelContextChangedHandler(TestWebUserControl_LabelContextChanged);
    }

现在我们运行程序,点击页面第二个按钮,效果如图所示这:


7.控件内客户端角本访问服务器控件的方法

这个问题实际上并不属于 Web 用户控件开发的范畴,但实际开发中多多少少会碰到这个问题,所以本着我这“牵牛花”的脾气就把它“牵”进来了,哈哈。

有人要问了,为什么控件内客户端角本访问服务器控件会是一个问题呢,这主要是因为,ASP.NET在将页面解释成客户端浏览器使用的页面时,将用户控件内的服务器控件ID做了一定的改动。如在咱们开发的这个用户控件里有一个 TextBox 控件,ID本来是 TextBox1 ,但在解释后的页面里它变成了 TestWebUserControl1_TextBox1,我们通过在浏览器里查看源代码可以看到,如下所示:
<input name="TestWebUserControl1$TextBox1" type="text" id="TestWebUserControl1_TextBox1" />

也就是说,用户控件被解释成客户端页面后,其中的服务器控件的ID规则是用户控件ID_服务器控件ID,知道这个规律我们就好办了。

编辑 TestWebUserControl.ascx ,切换到[设计]视图,从 HTML 面板拖一个 Input(Button) 控件(注意:这里要的是一个客户端控件)。再切换到[源视图]为其添加 onclick 属性,设成调用一个客户端函数 ShowTextBoxContext ,而这个函数要操作用户控件里的一个服务器控件,完整代码如下:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TestWebUserControl.ascx.cs" Inherits="TestWebUserControl" %>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<input id="Button2" type="button" value="button" onclick="ShowTextBoxContext(<%= TextBox1.ClientID%>)"/>

<script type="text/javascript" language="javascript">
    
function ShowTextBoxContext(obj)
    {
        alert(obj.value);
    }
</script>

注意这里的
<%= TextBox1.ClientID%>,为了获取客户端的对象,我们执行了一个服务端操作,“<%=”和 “%>”之间的代码将会在服务端运行,如此而己,是不是很简单?

现在我们运行程序,在第一个文本框里输入“开发和使用 Web 用户控件,OK!!!”,点击用户控件中刚添加的客户端 Button 按钮,将弹出一个对话框,显示我们填写的内容,效果如图所示:



另:如果使用的是外链角本而非这种内嵌的,那么这种访问方法并不能胜任。我的解决方案是将被访问的服务器控件放到一个 DIV 层里(它本来就是客户端组件),这样在客户端通过先查找到这个 DIV 层,再访问它的处Children 属性,就可以获取到相应的控件了。但由于在用户控件里使用这种外链角本将来在部署上多少有点麻烦,不建议使用,所以就没有列出详细的解决方案。

8.代码下载

下载地址:http://files.cnblogs.com/reonlyrun/WebUserControlTaste.rar
posted @ 2009-09-22 17:39 MYGIS_3 阅读(142) 评论(0) 编辑


转自:http://blog.csdn.net/oanqoanq/archive/2009/02/20/3913814.aspx

发现为本文起一个合适的标题还不是那么容易,呵呵,所以在此先说明下本文的两个目的:
1)介绍javascript中的eval函数的用法
2)如何在函数内执行全局代码

先来说eval的用法,内容比较简单,熟悉的可以跳过。
eval
函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句。如果s语句执行结果是一个值,则返回此值,否则返回undefined
需要特别注意的是对象声明语法“{}”并不能返回一个值,需要用括号括起来才会返回值,简单示例如下:

var code1='"a" + 2';    //表达式
var code2='{a:2}';      //语句
alert(eval(code1));     //->'a2'
alert(eval(code2));     //->undefined
alert(eval('(' + code2 + ')'));    //->[object Object]

        可以看到,对于对象声明语句来说,仅仅是执行,并不能返回值。为了返回常用的“{}”这样的对象声明语句,必须用括号括住,以将其转换为表达式,才能返回其值。这也是使用JSON来进行Ajax开发的基本原理之一。在例子中可以清楚的看到,第二个alert语句输出的是undefined,而第三个加了括号后输出的是语句表示的对象。

            现在来说本文的重点,如何在函数内执行全局代码。为了说明这个问题,先看一个例子:

var s='global';    //定义一个全局变量
function demo1(){
    
eval('var s="local"');
}
demo1();
alert(s);    
//->global

         很好理解,上面的demo1函数等价于:function demo1(){var s='local';},其中定义了一个局部变量s
       
所以最后的输出是global并不是什么奇怪的事情,毕竟大家都能很清楚的区分局部变量和全局变量。
       
仔细体会一下,可以发现eval函数的特点,它总是在调用它的上下文变量空间(也称为:包,closure)内执行,无论是变量定义还是函数定义都是如此,所以如下的代码会产生函数未定义的错误:

var s='function test(){return 1;}';     //一个函数定义语句
function demo2(){
    
eval(s);
}
demo2();
alert(test());    
//->error:test is not defined

        这是因为test函数在局部空间定义,demo2函数内可以访问到,外面就访问不到了。


        
而在实际的Ajax开发中,有时我们需要从服务器动态获取代码来执行,以减轻一次载入代码过多的问题,或者是一些代码是通过Javascript自身生成的,希望用eval函数来使其执行。
但这样的动态获取代码的工作一般在函数内完成,比如:

function loadCode(){
    
var code=getCode();
    
eval(code);
}

       可见eval不可能在全局空间内执行,这就给开发带来了不少问题,也看到过很多人为此郁闷。

        不过现在偶终于找到了解决办法,嘿嘿,可以同时兼容IEFirefox,方法如下:

var X2={}    //my namespace:)
X2.Eval=function(code){
if(!!(window.attachEvent && !window.opera)){
  
//ie
   execScript(code);
}
else{
  
//not ie
   window.eval(code);
}
}

        现在如果要想在函数内定义全局代码,就可以通过调用X2.Eval(code)方法,一个例子如下:

var s='global';
function demo3(){
X2.Eval(
'var s="local"');
}
demo3();
alert(s);
//->'local'

        可见,在demo3函数内重新定义了全局变量s="local"
       
需要注意的是X2.Eval并不返回值,如果要进行表达式的求值,还是用系统的eval函数。X2.Eval设计为仅做全局代码定义用。

        其实看到这里,或许有人感觉问题也太容易解决了点,呵呵,但发现这个办法倒是需要些运气和技巧的:
1)对于IE浏览器,默认已经提供了这样的函数:execScript,用于在全局空间执行代码,只是知道的人还不多。
2)对于Firefox浏览器,直接调用eval函数,则在调用者的空间执行;如果调用       window.eval则在全局空间执行。这个知道的人估计就更少了。毕竟alert(eval==window.eval)返回true

         Firefoxeval函数的特点的确是很令人奇怪的,但从javascript规范中倒也能找到其来源:

If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its
name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to,
an EvalError exception may be thrown.

      意思大概就是说eval函数的执行是和调用者相关的,但并没有说其执行上下文的问题。所以IEFirefox孰是孰非也就很难说了,大家知道解决办法就好。

 

posted @ 2009-09-20 22:59 MYGIS_3 阅读(97) 评论(0) 编辑
摘要: 声明:转载 触发器设计技巧和实例在数据库设计中,有两种方法可设定自动化的资料处理规则,一种是条件约束,一种是触发器,一般而言,条件约束比触发器较容易设定及维护,且执行效率较好,但条件约束只能对资料进行简单的栏位检核,当涉及到多表操作等复杂操作时,就要用到触发器了. 一个数据库系统中有两个虚拟表用于存储在表中记录改动的信息,分别是: 虚拟表inserted 虚拟表deleted在表记录新增时 存放新...阅读全文
posted @ 2009-09-16 15:56 MYGIS_3 阅读(16) 评论(0) 编辑
摘要: 声明:转载一.先简单说说触发器的机制。每个触发器都会创建两个逻辑专用表:inserted表和deleted表,其结构跟被触发表的结构完全相同,执行后,这两个表都会被删除。执行insert插入语句时,inserted表存放要插入的所有行,执行delete删除操作时,deleted表存放要删除的所有行,执行update更新操作相当于先执行一个delete操作再执行有个insert操作,原记录存放于de...阅读全文
posted @ 2009-09-16 15:48 MYGIS_3 阅读(31) 评论(0) 编辑
摘要: 自:http://blog.csdn.net/myloy/archive/2009/08/27/4488398.aspxHttpCookie 类获取和设置各 Cookie 的属性。 HttpCookieCollection 类提供存储、检索和管理多个 Cookie 的方法。ASP.NET 包含两个内部 Cookie 集合。通过 HttpRequest 对象的 Cookies 集合访问的集合,包含以...阅读全文
posted @ 2009-09-14 19:56 MYGIS_3 阅读(112) 评论(0) 编辑