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

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

2010-08-03 13:32 金色海洋(jyk)阳光男孩 阅读(...) 评论(...) 编辑 收藏

 

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

 

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

 

  所以拿出来抖落抖落。

 

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

 

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

 

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

 

用接口实现事件的一种方法,只是玩玩。_第1张图片 

 

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

用接口实现事件的一种方法,只是玩玩。_第2张图片

    代码如下

 

 

代码
namespace  Nature.MyEvent
{
    
///  
    
///  定义一个接口
    
///  

     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> " )]
    
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( " ================
控件内部事件——开始
" );
                        
base .Page.Response.Write(myEvent.MyName  +   "
" );
                        myEvent.Test 
=   base .Page.Request.Form[ " EventTest1$Txt_Test " ]; //  DateTime.Today.ToString();

                        
// 调用外部事件
                        myEvent.Event( base .Page);

                        
base .Page.Response.Write( " 控件内部事件——结束


" );
                    }
                }
            }

        }



        
#region  设计时支持
        
///  
        
///  设计时支持
        
///  

        
///  
         protected   override   void  Render(HtmlTextWriter output)
        {
            
if  (( base .Site  !=   null &&   base .Site.DesignMode)
            {
                output.Write(
"  用接口实现事件的测试
" );
            }
            
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" >
           
//
            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  =   "
MyName:{0};
MyTest:{1}
" ;
            page.Response.Write(
"
外部事件——开始
" );

            page.Response.Write(
string .Format(str,  this ._MyName,  this ._MyTest));

            page.Response.Write(
" 外部事件——结束

" );
        }

    }

}

 

 

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

 

      就是在自定义控件内部定义一个List,保存外部申请的接口,Default.aspx.cs往控件里加“接口”就可以了。然后是调用的问题。

 

      调用的部分比较简单,直接在CreateChildControls()里面就调用了。

 

实现了几个功能:

1、在控件内部调用了外部的方法。

2、外部设置的属性可以传递到控件内部。

3、控件内部设置的属性也可以传递给外部。

4、可以获取表单值。

 

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

 

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

 

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

  

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

 

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

 

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

 

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

 

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

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

 

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

 

你可能感兴趣的:(用接口实现事件的一种方法,只是玩玩。)