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

简介:   前一阵子,firelong说,应该用接口实现事件,而不应该用委托。我就希望他能给出一个用接口实现事件的方法,我是一直等呀,等到了现在也没有看到。     昨天又看到了,Snake@Net  说不要把接口和委托给混淆了的文章。

 

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

 

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

 

  所以拿出来抖落抖落。

 

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

 

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

 

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

 

 

 

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

    代码如下

 

 

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

        
string  Test
        {
            
get ;
            
set ;
        }

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

    }
}

 

 

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
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。

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
<% @ 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 >

 

 

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
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 下载。

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

 

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

 

相关文章
|
数据可视化 Java
Java中的事件监听知识点&动作监听简单实现(含源码阅读)
监听分为三类:键盘监听、鼠标监听 和 动作监听,看到这些名词可能有点懵,监听是个啥,那么首先我们来理解一下绑定监听:当事件源(按钮)上发生了某个事件(单击),就执行某段代码(输出“您已点击按钮”)
396 0
Java中的事件监听知识点&动作监听简单实现(含源码阅读)
如何使用嵌套组件<MyLeft>,不是说用就用,要先注册
如何使用嵌套组件<MyLeft>,不是说用就用,要先注册
|
前端开发
前端学习笔记202305学习笔记第二十五天-事件注册和调用
前端学习笔记202305学习笔记第二十五天-事件注册和调用
38 0
|
C# Windows
C#OOP之十一 委托和事件
C#OOP之十一 委托和事件
81 0
|
开发工具 Android开发
RxBus 一个简易、非反射的Android事件通知库
RxBus 一个简易、非反射的Android事件通知库
796 0
RxBus 一个简易、非反射的Android事件通知库
|
JavaScript 前端开发
如何确保你的构造函数只能被new调用,而不能被普通调用?| 踩坑日记
如何确保你的构造函数只能被new调用,而不能被普通调用?| 踩坑日记
624 0
如何确保你的构造函数只能被new调用,而不能被普通调用?| 踩坑日记
|
监控 C#
艾伟_转载:把委托说透(1):开始委托之旅 委托与接口
委托,本是一个非常基础的.NET概念,但前一阵子在园子里却引起轩然大波。先是Michael Tao的随笔让人们将委托的写法与茴香豆联系到了一起,接着老赵又用一系列文章分析委托写法的演变,并告诫“嘲笑孔乙己的朋友们,你们在一味鄙视“茴”的四种写法的同时,说不定也失去了一个了解中国传统文化的机会呢!”。
1006 0
|
JavaScript 前端开发 Java
微信分享接口配置和调用
原文:http://blog.csdn.net/wangjuan_01/article/details/51919551   步骤一:绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
1677 0