在 Web Forms 開發中,將「使用者註冊」等重複 UI 邏輯封裝為使用者控制項,並透過事件將資料回傳給父頁面處理,是實現關注點分離的經典模式。本文完整示範:前端 jQuery 驗證、ASCX 控制項定義事件/委派、父頁面訂閱事件並處理資料持久化。
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="myRegister1.ascx.cs" Inherits="WebApp.myRegister" %>
<script src="js/Jquery1.7.js" type="text/javascript"></script>
<script type="text/javascript">
function Register() {
if ($('#myRegister1_txtUserName').val() == '') {
$('#spanUserName').text('請輸入使用者名稱'); return false;
}
if ($('#myRegister1_txtPwd').val() == '') {
$('#spanPwd').text('請輸入密碼'); return false;
}
if ($('#myRegister1_txtPwd1').val() == '') {
$('#spanPwd1').text('請確認密碼'); return false;
}
if ($('#myRegister1_txtPwd1').val() != $('#myRegister1_txtPwd').val()) {
$('#spanPwd1').text('兩次密碼不一致'); return false;
}
if ($('#myRegister1_txtEmail').val() == '') {
$('#spanEmail').text('請輸入電子郵件'); return false;
}
return true;
}
</script>
<table>
<tr><td>使用者名稱:</td><td><asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td><td><span id="spanUserName"></span></td></tr>
<tr><td>密碼:</td><td><asp:TextBox ID="txtPwd" TextMode="Password" runat="server"></asp:TextBox></td><td><span id="spanPwd"></span></td></tr>
<tr><td>確認密碼:</td><td><asp:TextBox ID="txtPwd1" TextMode="Password" runat="server"></asp:TextBox></td><td><span id="spanPwd1"></span></td></tr>
<tr><td>電子郵件:</td><td><asp:TextBox ID="txtEmail" runat="server"></asp:TextBox></td><td><span id="spanEmail"></span></td></tr>
<tr><td></td><td>
<asp:Button ID="btnRegister" runat="server" Text="註冊"
OnClick="btnRegister_Click" OnClientClick="return Register()" />
</td><td><asp:Label ID="Label1" runat="server" Text=""></asp:Label></td></tr>
</table>
public partial class myRegister : System.Web.UI.UserControl
{
// 1. 定義委派型別
public delegate void MyRegisterDelegate();
// 2. 宣告事件
public event MyRegisterDelegate On_MyRegister;
// 3. 靜態類別暫存表單資料(示範用,實務建議用 ViewState 或傳遞 EventArgs)
public class MyRegister
{
public static string userName { get; set; }
public static string pwd { get; set; }
public static string email { get; set; }
public static bool isBool { get; set; }
}
protected void Page_Load(object sender, EventArgs e) { }
protected void btnRegister_Click(object sender, EventArgs e)
{
if (On_MyRegister != null)
{
// 填充靜態屬性供父頁面讀取
MyRegister.userName = txtUserName.Text;
MyRegister.pwd = txtPwd.Text;
MyRegister.email = txtEmail.Text;
// 觸發事件
On_MyRegister();
// 根據父頁面處理結果顯示訊息
Label1.Text = MyRegister.isBool ? "註冊成功" : "註冊失敗";
}
}
}
<%@ Register Src="~/myRegister1.ascx" TagPrefix="uc1" TagName="myRegister" %>
<uc1:myRegister ID="myRegister1" runat="server" />
public partial class WebForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 訂閱控制項事件
this.myRegister1.On_MyRegister += new MyRegisterDelegate(myRegister1_On_MyRegister);
}
void myRegister1_On_MyRegister()
{
// 呼叫資料存取邏輯,回傳是否成功
MyRegister.isBool = Writer(MyRegister.userName, MyRegister.pwd, MyRegister.email);
}
private bool Writer(string userName, string pwd, string email)
{
try
{
using (Stream stream = File.Open(@"E:\new.txt", FileMode.Append, FileAccess.Write))
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine("使用者:{0}, 密碼:{1}, 信箱:{2}", userName, pwd, email);
}
return true;
}
catch { return false; }
}
}
public delegate void MyRegisterDelegate(); 定義事件簽章。public event MyRegisterDelegate On_MyRegister; 讓父頁面可訂閱。On_MyRegister() 觸發。Page_Load 中 += new MyRegisterDelegate(處理方法)。EventArgs 傳遞強型別資料,避免多執行緒/併發問題。若需傳遞豐富資料,請繼承 EventArgs 建立 RegisterEventArgs,委派改為 EventHandler<RegisterEventArgs>,事件觸發時 On_MyRegister(this, new RegisterEventArgs(userName, pwd, email)),父頁面直接從 e.UserName 取值,更符合 .NET 事件設計規範。