前一陣子,firelong說,應該用接口實作事件,而不應該用委托。我就希望他能給出一個用接口實作事件的方法,我是一直等呀,等到了現在也沒有看到。
是以拿出來抖落抖落。
這個隻是展現了一個簡單的思路,我并不想用他來證明什麼,隻是寫着玩的。
==========================
建立兩個項目,一個是web項目,一個是自定義伺服器控件的項目。

伺服器控件的項目裡定義一個控件(EventTest)和一個接口(IEvent)。
代碼如下
代碼
namespace Nature.MyEvent
{
/// <summary>
/// 定義一個接口
/// </summary>
public interface IEvent
{
string MyName
{
get;
set;
}
string Test
void Event(System.Web.UI.Page page);
}
}
[DefaultProperty("Text")]
[ToolboxData("<{0}:EventTest runat=server></{0}:EventTest>")]
public class EventTest : WebControl, INamingContainer
TextBox txt = new TextBox();
HtmlInputButton btn = new HtmlInputButton();
private List<IEvent> _EventList = new List<IEvent>() ;
public List<IEvent> EventList
get { return _EventList; }
set { _EventList = value; }
protected override void CreateChildControls()
base.CreateChildControls();
//建立一個文本框
txt.ID = "Txt_Test";
this.Controls.Add(txt);
//建立一個HTML的按鈕
btn.ID = "Btn_Test";
btn.Name = "event";
btn.Value = "點選我";
//添加一個前台js事件
btn.Attributes.Add("onclick", "test(this)");
this.Controls.Add(btn);
if (base.Page.IsPostBack)
{
//處理事件
if (_EventList != null)
{
//有外部申請的事件
foreach (IEvent myEvent in _EventList)
{
base.Page.Response.Write("================<BR>控件内部事件——開始<BR>");
base.Page.Response.Write(myEvent.MyName + "<BR>");
myEvent.Test = base.Page.Request.Form["EventTest1$Txt_Test"];// DateTime.Today.ToString();
//調用外部事件
myEvent.Event(base.Page);
base.Page.Response.Write("控件内部事件——結束<BR><BR><BR>");
}
}
}
#region 設計時支援
/// <summary>
/// 設計時支援
/// </summary>
/// <param name="output"></param>
protected override void Render(HtmlTextWriter output)
if ((base.Site != null) && base.Site.DesignMode)
output.Write("<div style='TEXT-ALIGN: center;width:100%'> 用接口實作事件的測試</div>");
else
//Page_Click();
base.Render(output);
#endregion
在web項目裡的Default.aspx裡面把自定義控件拖拽過來,在加點js腳本。Default.aspx.cs裡在寫幾行代碼。最重要的是定義一個類(MyEvent1),實作一下接口IEvent。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Nautre.MyEvent._Default" %>
<%@ Register assembly="MyEvent" namespace="Nature.MyEvent" tagprefix="cc1" %>
<!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>
<script language="javascript">
function test(me)
alert("您單擊了這個按鈕,并且觸發了一個事件,其實是表單送出。\n按确定後送出表單");
__doPostBack(me.id,"");
</script>
</head>
<body>
<form id="form1" runat="server">
<input type="hidden" name="__myEVENTTARGET" id="__myEVENTTARGET" value="" />
<input type="hidden" name="__myEVENTARGUMENT" id="__myEVENTARGUMENT" value="" />
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__myEVENTTARGET.value = eventTarget;
theForm.__myEVENTARGUMENT.value = eventArgument;
theForm.submit();
}
//]]>
</script>
<div>
<cc1:EventTest ID="EventTest1" runat="server" />
</div>
</form>
</body>
</html>
namespace Nautre.MyEvent
public partial class _Default : System.Web.UI.Page
protected override void OnInit(EventArgs e)
base.OnInit(e);
MyEvent1 e1 = new MyEvent1();
e1.MyName = "第一個事件";
MyEvent1 e2 = new MyEvent1();
e2.MyName = "第二個事件";
this.EventTest1.EventList.Add(e1);
this.EventTest1.EventList.Add(e2);
protected void Page_Load(object sender, EventArgs e)
public class MyEvent1 : Nature.MyEvent.IEvent
private string _MyName = "";
public string MyName
get{return _MyName;}
set { _MyName = value; }
private string _MyTest = "";
public string Test
get { return _MyTest; }
set { _MyTest = value; }
public void Event(System.Web.UI.Page page)
//處理自己的事件
string str = "<BR>MyName:{0};<BR>MyTest:{1}<BR>";
page.Response.Write("<BR>外部事件——開始<BR>");
page.Response.Write(string.Format(str, this._MyName, this._MyTest));
page.Response.Write("外部事件——結束<BR><BR>");
=================================
就是在自定義控件内部定義一個List,儲存外部申請的接口,Default.aspx.cs往控件裡加“接口”就可以了。然後是調用的問題。
調用的部分比較簡單,直接在CreateChildControls()裡面就調用了。
實作了幾個功能:
1、在控件内部調用了外部的方法。
2、外部設定的屬性可以傳遞到控件内部。
3、控件内部設定的屬性也可以傳遞給外部。
4、可以擷取表單值。
這裡有一個很明顯的缺點,每一種事件的處理方法,都要去定義一個類,并且實作一個接口,這個顯然很麻煩。
================================
這是一個簡單的思路,我不想用他證明用接口實作事件是更好的方法,也不想用他證明某個觀點是正确的或者某個觀點是錯誤的,更不想說微軟的對與事件的解決方式有問題。
隻是實作同一個目的(事件)的另一種方法。
這種方法還有很多問題,比如如何解決按鈕和接口的對應問題?(這裡就是一個按鈕,一個接口,表單送出就是調用了,沒有做是否對應的判斷)
還有事件冒泡,還有效率、穩定性、可讀性、用着是不是友善等問題。
這個隻是玩一玩,是以請大家不要較真,呵呵。
順便問個問題,我以前上傳的檔案和圖檔怎麼都看不到了?