很多时候,我们需要用到User Control,将部份UI或业务逻辑包装,下面将UserControl包装成Asp.Net ajax 控件:
简单示例:
(ASCX) 这一段代码就不解释了:
 1 <%@ Control Language="C#" AutoEventWireup="true" CodeFile="LoginPanel.ascx.cs" Inherits="LoginPanel" %>
 2 <table>
 3     <tr>
 4         <td>
 5             Login Name:
 6         </td>
 7         <td>
 8             <asp:TextBox ID="UserName" Ruant="Server"></asp:TextBox>
 9         </td>
10     </tr>
11     <tr>
12         <td>
13             Password:
14         </td>
15         <td>
16             <asp:TextBox ID="Password" TextMode="Password" Ruant="Server"></asp:TextBox>
17         </td>
18     </tr>
19 </table>

(LoginPanel.js)

 1 <script type="text/javascript">
 2     /// <reference name="MicrosoftAjax.js"/>
 3     Type.registerNamespace("CsharpFarmer");
 4     CsharpFarmer.LoginPanel= function(element) {
 5         CsharpFarmer.LoginPanel.initializeBase(this, [element]);
 6         this.userName = null;
 7         this.password = null;
 8     }
 9     CsharpFarmer.LoginPanel.prototype = {
10         initialize: function() {
11             CsharpFarmer.LoginPanel.callBaseMethod(this'initialize');
12             // Add custom initialization here
13         },
14         get_userName: function() {
15             return this.userName ;
16         },
17         set_userName: function(value) {
18             this.userName = value;
19         },
20         get_password: function() {
21             return this.password ;
22         },
23         set_password: function(value) {
24             this.password = value;
25         },
26         dispose: function() {
27             //Add custom dispose actions here
28             CsharpFarmer.LoginPanel.callBaseMethod(this'dispose');
29             delete this.userName;
30             delete this.password;
31         }
32     }
33     CsharpFarmer.LoginPanel.registerClass(CsharpFarmer.LoginPanel, Sys.UI.Control);
34 </script>

(控件相对应的js,注意get和set方法必须成对出现,与属性以"_"隔开,),至于为什么,只是一种规定,查看MsAjax:
中:Sys$Component$_setProperties:
Code

LoginPanel.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.UI;
 6 using System.Web.UI.WebControls;
 7 using System.Text;
 8 
 9 /// <summary>
10 /// LoginPanel 
11 /// </summary>
12 public partial class LoginPanel : System.Web.UI.UserControl, IScriptControl
13 {
14 
15     protected void Page_Load(object sender, EventArgs e)
16     {
17 
18     }
19 
20     protected override void Render(HtmlTextWriter writer)
21     {
22         writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
23         writer.RenderBeginTag("Div");
24         base.Render(writer);
25         writer.RenderEndTag();
26     }
27 
28     protected override void OnPreRender(EventArgs e)
29     {
30         base.OnPreRender(e);
31         var sm = ScriptManager.GetCurrent(this.Page);
32         sm.RegisterScriptControl<LoginPanel>(this);
33         sm.RegisterScriptDescriptors(this);
34     }
35 
36     
37     #region IScriptControl
38 
39     public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
40     {
41         var descriptor = new ScriptControlDescriptor("CsharpFarmer.LoginPanel"this.ClientID);
42         descriptor.AddElementProperty("userName", UserName.ClientID);
43         descriptor.AddElementProperty("password", Password.ClientID);
44         yield return descriptor;
45     }
46 
47     public IEnumerable<ScriptReference> GetScriptReferences()
48     {
49         var sr = new ScriptReference("~/LoginPanel.js");
50         yield return sr;
51     }
52 
53     #endregion
54 }
55 


这一段代码中应当注意,必须实现IScriptControl接口,
另个,OnPreRender 和 Render 方法应注意.
在OnPresRender里注册这个控件:
对于一个可视化的控件,必段承载在HTML元素之上,所以,
在Render方法中,将其放入Div中,注意ID

当我们把控件放入Aspx page 时:
我们在js中可以得用$find("id") 得到这个控件:


第一次写,多关照.