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


      前一阵子,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;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 下载。

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

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

  • 相关阅读:
    Python匹马行天下之_循环
    Hello world!
    Python匹马天下行之python基本语法
    Python匹马行天下之python之父
    Python匹马行天下之面向对象
    Python匹马行天下之运算符
    Python匹马行天下之初识python!
    跨域问题学习记录 CORS解决的2种方法
    Linux系统运维成长记
    关于倒计时new Date().getTime()出现NaN
  • 原文地址:https://www.cnblogs.com/jyk/p/1791107.html
Copyright © 2020-2023  润新知