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

 

  前一阵子,firelong说,应该用接口实现事件,而不应该用委托。我就希望他能给出一个用接口实现事件的方法,我是一直等呀,等到了现在也没有看到。

 

  昨天又看到了,Snake@Net  说不要把接口和委托给混淆了的文章。也许我就把他们给混淆了吧。他的文章没仔细看,不过我倒是突然想到了一个用接口实现事件的方法,写了一个简单的demo测试了一下,居然还成功了。

 

  所以拿出来抖落抖落。

 

  这个只是体现了一个简单的思路,我并不想用他来证明什么,只是写着玩的。

 

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

 

  建立两个项目,一个是web项目,一个是自定义服务器控件的项目。

 

 

 

  服务器控件的项目里定义一个控件(EventTest)和一个接口(IEvent)。

    代码如下

 

 

代码

namespace Nature.MyEvent
{
    /// <summary>
    /// 定义一个接口
    /// </summary>
    public interface IEvent
    {
        string MyName
        {
            get;
            set;
        }

        string Test
        {
            get;
            set;
        }

         void Event(System.Web.UI.Page page);

    }
}

 

 

 

 

代码

namespace Nature.MyEvent
{
    [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、可以获取表单值。

 

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

 

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

 

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

  

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

 

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

 

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

 

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

 

  最后,如果感兴趣的话,可以点 接口实现事件.rar 下载。

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

 

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

 

时间: 2024-09-21 10:35:32

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

Xamarin for android:为button设置click事件的几种方法

原文:Xamarin for android:为button设置click事件的几种方法 在Xamarin中一个最基础的事情,就是为一个button指定click事件处理方法,可是即使是这么一件事也有好几种方法,我在下面列出几种.推荐初学者参考. 注意,1 以下方法并不是全部方法:2 以下方法都是在Activity类中使用.其中方法1.2通常在你的Activity类的OnCreate中调用,且调用前button对象已经初始化. 方法1:使用委托 button.Click += delegate

js 绑定事件的几种方法 addEventListener()

看代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>添加事件的几种方法</title> <style type="text/css"> div{ width: 200px; height: 100px; background: #CCCCCC; border: 1px solid #008000; /*dis

JS创建事件的三种方法(实例代码)_基础知识

1.普通的定义方式 <input type="button" name="Button" value="确定" onclick="Sfont=prompt('请在文本框中输入红色','红色',' 提示框 '); if(Sfont=='红色'){ form1.style.fontFamily='黑体'; form1.style.color='red'; }" /> 这是最常见的一种定义方式,直接将JS事件定义在需要的

【更正】“给自定义控件(Web Control)添加事件的几种方法”有一个不太准确的地方。

    给自定义控件(Web Control)添加事件的几种方法.前两种方法可以不实现IPostBackEventHandler           上一篇写了一下如何在自定义控件里面添加事件,由简单的开始,一步一步实现了几种添加事件的方式,由于当时只给自定义控件添加了一种外部事件,测试的时候没有什么问题,但是后来在写分页控件的时候,我给分页控件加了两种外部事件,然后测试的时候就出现了一个问题,本来只想调用外部的一种事件,结果外部的两种事件都被调用了.分析了一下,public event Eve

FLASH中响应键盘事件的四种方法

响应 响应键盘的方法作为AS中的一个重要组成部分,在如今已经越来越广泛的使用,尤其是在 FLASH游戏制作中,如果缺少了响应键盘的方法,那是不可能的,而响应键盘的方法主要的四种,分别是: 1.利用按钮进行检测 2.利用KEY对象 3.利用键盘侦听的方法 4.利用影片剪辑的keyUp和keyDown事件来实现响应键盘 只有熟练掌握了这些方法,然后加以变通的话,就会得到很多意想不到的效果,下面我就结合理论和自己的想法简要的介绍一下. 第一种响应键盘的方法:利用按钮进行检测来实现响应键盘 在按钮的on

js 动态加载事件的几种方法总结_javascript技巧

有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添加事件,这就涉及到浏览器兼容性问题了,以下谈及的几种方法,我们也常常混合使用. 方法一.setAttributevar obj = document.getElementById("obj");obj.setAttribute("onclick", "javascript:alert('测试');"); 这里利用 setAttribute 指定 onclick 属

android中在Activity中响应ListView内部按钮的点击事件的两种方法_Android

最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应? 对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在Activity中实现该接口,从而实现对点击事件的响应. 下班后思考了一下,觉得有两种方式都能比较好的实现:使用接口回调和使用抽象类回调. 正好可以复习一下接口和抽象类的区别,于是写了两个Demo: 1.使用接口回调: Adapter类 package com.ivan.adapter; import

android中在Activity中响应ListView内部按钮的点击事件的两种方法

最近交流群里面有人问到一个问题:如何在Activity中响应ListView内部按钮的点击事件,不要在Adapter中响应? 对于这个问题,我最初给他的解答是,在Adapter中定义一个回调接口,在Activity中实现该接口,从而实现对点击事件的响应. 下班后思考了一下,觉得有两种方式都能比较好的实现:使用接口回调和使用抽象类回调. 正好可以复习一下接口和抽象类的区别,于是写了两个Demo: 1.使用接口回调: Adapter类 package com.ivan.adapter; import

android为按钮添加事件的三种方法

 Android中为按钮添加事件一般有三种方法,这里总结一下,当然其实这完全是java基础内容. 1.内部类: ? 代码片段,双击复制   btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { ... } });   这种方法适合只为单个按钮添加事件,当按钮较多的时候,就要重复写onClick()方法,这样不是最佳的在做法. 2.创建独立的类: ? 代码片段,双击复制   btn.setOnCli