天天看点

用接口实现事件的一种方法,只是玩玩。

  前一阵子,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、可以获取表单值。

这里有一个很明显的缺点,每一种事件的处理方法,都要去定义一个类,并且实现一个接口,这个显然很麻烦。

================================

  这是一个简单的思路,我不想用他证明用接口实现事件是更好的方法,也不想用他证明某个观点是正确的或者某个观点是错误的,更不想说微软的对与事件的解决方式有问题。

  

  只是实现同一个目的(事件)的另一种方法。

  这种方法还有很多问题,比如如何解决按钮和接口的对应问题?(这里就是一个按钮,一个接口,表单提交就是调用了,没有做是否对应的判断)

  还有事件冒泡,还有效率、稳定性、可读性、用着是不是方便等问题。

  这个只是玩一玩,所以请大家不要较真,呵呵。

顺便问个问题,我以前上传的文件和图片怎么都看不到了?

继续阅读