这个问题实际上并不属于 Web 用户控件开发的范畴,但实际开发中多多少少会碰到这个问题,所以本着我这“牵牛花”的脾气就把它“牵”进来了,哈哈。
有人要问了,为什么控件内客户端角本访问服务器控件会是一个问题呢,这主要是因为,ASP.NET在将页面解释成客户端浏览器使用的页面时,将用户控件内的服务器控件ID做了一定的改动。如在咱们开发的这个用户控件里有一个 TextBox 控件,ID本来是 TextBox1 ,但在解释后的页面里它变成了 TestWebUserControl1_TextBox1,我们通过在浏览器里查看源代码可以看到,如下所示:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> < input name = " TestWebUserControl1$TextBox1 " type = " text " id = " TestWebUserControl1_TextBox1 " />
也就是说,用户控件被解释成客户端页面后,其中的服务器控件的ID规则是 用户控件ID_服务器控件ID,知道这个规律我们就好办了。
编辑 TestWebUserControl.ascx ,切换到[设计]视图,从 HTML 面板拖一个 Input(Button) 控件(注意:这里要的是一个客户端控件)。再切换到[源视图]为其添加 onclick 属性,设成调用一个客户端函数 ShowTextBoxContext ,而这个函数要操作用户控件里的一个服务器控件,完整代码如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> <% @ 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 属性,就可以获取到相应的控件了。但由于在用户控件里使用这种外链角本将来在部署上多少有点麻烦,不建议使用,所以就没有列出详细的解决方案。
有人要问了,为什么控件内客户端角本访问服务器控件会是一个问题呢,这主要是因为,ASP.NET在将页面解释成客户端浏览器使用的页面时,将用户控件内的服务器控件ID做了一定的改动。如在咱们开发的这个用户控件里有一个 TextBox 控件,ID本来是 TextBox1 ,但在解释后的页面里它变成了 TestWebUserControl1_TextBox1,我们通过在浏览器里查看源代码可以看到,如下所示:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> < input name = " TestWebUserControl1$TextBox1 " type = " text " id = " TestWebUserControl1_TextBox1 " />
也就是说,用户控件被解释成客户端页面后,其中的服务器控件的ID规则是 用户控件ID_服务器控件ID,知道这个规律我们就好办了。
编辑 TestWebUserControl.ascx ,切换到[设计]视图,从 HTML 面板拖一个 Input(Button) 控件(注意:这里要的是一个客户端控件)。再切换到[源视图]为其添加 onclick 属性,设成调用一个客户端函数 ShowTextBoxContext ,而这个函数要操作用户控件里的一个服务器控件,完整代码如下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> <% @ 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 属性,就可以获取到相应的控件了。但由于在用户控件里使用这种外链角本将来在部署上多少有点麻烦,不建议使用,所以就没有列出详细的解决方案。