Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1107404
  • 博文数量: 141
  • 博客积分: 3161
  • 博客等级: 中校
  • 技术积分: 3011
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-27 14:53
文章存档

2012年(28)

2011年(113)

分类: 系统运维

2011-09-29 12:19:54

 

    前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是行不通。如果大家开发的是WinForm中的事件,之前的定义可能没有什么大的问题,只是在效率方法欠考虑而且,还是可以运行的。

   

    下面我们就回到ASP.NET中的事件。

 

    大家也许看了我们之前定义的事件,确实,事件一般是那么定义的,但是那样定义事件后的,运行起来的效率不搞,因为那样定义事件后,编译器在编译事件代码的时候,会自动的为我们加入很多多线程安全的代码,就是说,虽然我们只是定义几行代码,大但是编译器为我们做了很多额外的事情,当然,这样代码的运行的效率可想而知。

 

    在很多的时候,我们自定义控件的事件不是需要考虑多线程安全等问题的,所我们就要改变代码,使其运行的更加好,我们就采用下面的方法:显示的申明事件:    

  1. //其实其实一个辅助的变量,用来做Hashtable中的”键“


  2.         private static object ValidateCreditCardFormKey = new object();
  3.         public event ValidateCreditCardFormEventHandler ValidateCreditCardForm
  4.         {
  5.             add
  6.             {
  7.                 Events.AddHandler(ValidateCreditCardFormKey, value);
  8.             }
  9.             remove
  10.             {
  11.                 Events.RemoveHandler(ValidateCreditCardFormKey, value);
  12.             }
  13.         }


  14.         protected void OnValidateCreditCardForm(ValidateCreditCardFormEventArgs args)
  15.         {
  16.             ValidateCreditCardFormEventHandler handler = Events[ValidateCreditCardFormKey]
  17.                                                                         as ValidateCreditCardFormEventHandler;
  18.             if (handler != null)
  19.                 handler(this, args);
  20.         }
 
    注意:其实就我们之前定义的事件的代码而言,编译器在在编译我们的代码的时候,也是编译成了上面的形式而且还额外的加上了一些安全的控制代码,这里,我们现在不要编译器生成,而是我们自己写出来,效率就高了。

 

    还有就是:如果一个事件在事件列表(是一个hashtable)已经注册了,当页面上有两个相同我们自定义控件,控件的事件也只是在注册一次,效率也高了。

 

    到这里一个事件就定义好了。

    现在做的事情就是要触发事件。即,点击“提交”按钮,就触发。

    我们先了理解一下流程:

    点击“提交”,整个页面就向服务器提交了,之后就开始了页面的生命周期。

    1.对页面进行解析,将原来页面中的源,如这样的标记解析成相应的html代码,当把页面解析完之后,页面在服务器就是html的样式了。(我这里说的很粗略,没有必要说的那么详细)。

 

    2.解析后的页面就开始检查,刚才是哪个控件引发的服务器回传,即,是点击了哪个按钮后,整个页面向服务器提交的,我们这里就是那个“提交”按钮。

 

    解析后的页面检查“提交”按钮的name是否和控件(CreditCardForm)的name相同,如果相同。再检查控件 CreditCardForm实现了IPostBackEventHandler接口,如果实现了,就引发我们之前定义的事件。

 

    我们的控件就和真正的服务器控件没有两样了。

    注意:上面的第3点:我们要按钮的name和CreditCardForm的name一样,这里的name我们无法用自己手动来设置他们的一样,因为CreditCardForm的名字是有页面来设置的,页面将其设置为:this.UniqueID,所以我们只能将按钮的名字设置为this.UniqueID,这样就可以了),所以我们要重写CreditCardForm5的一些属性:

 

  1. protected override string SubmitButtonName
  2.         {
  3.             get
  4.             {
  5.                 return this.UniqueID;
  6.             }
  7.         }

 

    还有,每一次页面提交给服务器后,解析页面的this.UniqueID都不一样。而且,如果在页面中同时有两个CreditCardForm,我们也要保证两个控件的其他控件,如输入框等等的name也不一样,所以要分别重写name。

 

  1. protected override string PaymentMethodListName
  2.         {
  3.             get
  4.             {
  5.                 return this.UniqueID + ":PaymentMethod";
  6.             }
  7.         }

  8.         protected override string CreditCardNoTextName
  9.         {
  10.             get
  11.             {
  12.                 return this.UniqueID + ":CreditCardNo";
  13.             }
  14.         }

  15.         protected override string CardholderNameTextName
  16.         {
  17.             get
  18.             {
  19.                 return this.UniqueID + ":CardholderName";
  20.             }
  21.         }

  22.         protected override string MonthListName
  23.         {
  24.             get
  25.             {
  26.                 return this.UniqueID + ":Month";
  27.             }
  28.         }

  29.         protected override string YearListName
  30.         {
  31.             get
  32.             {
  33.                 return this.UniqueID + ":Year";
  34.             }
  35.         }

          

    这里以后,下面我们就只要实现IPostBackEventHandler接口,就可以调用我们的事件了,实现IPostBackEventHandler接口,其实只有一个方法。而且也很简单,代码:

 

  1. //大家看看我们只是将之前的事件通知代码移到了这里。


  2.         void IPostBackEventHandler.RaisePostBackEvent(string args)
  3.         {
  4.             ValidateCreditCardFormEventArgs ve = new ValidateCreditCardFormEventArgs(
  5.                 PaymentMethodText, CreditCardNoText, CardholderNameText, ExpirationDateText);

  6.             OnValidateCreditCardForm(ve);
  7.         }

 

     这样以后,我们的控件就可以引发服务器回传了,即,当你点击“提交”按钮时,我们的浏览器的状态栏下面就有刷新的进度条了。

 

    注意,还有一个问题啊,我们确实能够使得我们的控件向服务器提交信息,但是服务器怎么来得到我们的提交的信息呢?

 

    并不是我们把信息向服务器提交后,就什么都不管了,然后服务器就”很听话的“进行验证。不是这样的,起码我们还要告诉服务器,我们提交了哪些要被验证的信息。

 

     那么服务器这样接受到我们的信息,,很简单,只要实现一个接口就可以了--IPostBackDataHandler。

 

     接口有两个方法,第一个就是LoadPostData方法,就是来获取我们的信息,并且判断我们这次提交的信息和上次有变化没有。

 

    上面的方法返回一个布尔的值,如果返回true,就自动的调用下一个方法RaisePostDataChangedEvent,大家可以根据方法的英文看到他们的作用。

 

    这里我们只是讲下LoadPostData方法,方法的完成写法是这样的: 

  1. bool LoadPostData(string postDataKey, NameValueCollection values)
  2.   {
  3.   
  4.   }

     看见方法不要害怕,方法的参数,前一个参数,我们不要管,只要看看后面的参数就可以了。

     

    我们的信息的提交,都是在相应的输入框,下拉框中写好了,传给服务器的,其实是以:键值对,传了的。     

     键:就是我们输入框等的名字,name

     值:就是输入的值。

 

    其实NameValueCollection就是一个哈希表,来存放键值对的。

 

    我们之前的所有输入的信息被包含成了一个NameValueCollection传到服务器,然后服务器就通过对应的“键”(name)来获取值,然后验证。

    代码如下:

 

  1. bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
  2.         {
  3.             string paymentMethod = values[PaymentMethodListName] == "0" ? "Master" : "Visa";
  4.             if (paymentMethod != PaymentMethodText)
  5.             {
  6.                 PaymentMethod = paymentMethod;
  7.                 hasPaymentMethodChanged = true;
  8.             }

  9.             string creditCardNo = values[CreditCardNoTextName];
  10.             if (creditCardNo != CreditCardNoText)
  11.             {
  12.                 CreditCardNoText = creditCardNo;
  13.                 hasCreditCardNoChanged = true;
  14.             }

  15.             string cardholderName = values[CardholderNameTextName];
  16.             if (cardholderName != CardholderNameText)
  17.             {
  18.                 CardholderNameText = cardholderName;
  19.                 hasCardholderNameChanged = true;
  20.             }

  21.             int month = int.Parse(values[MonthListName]);
  22.             int year = int.Parse(values[YearListName]);
  23.             DateTime expirationDate = new DateTime(year, month, 10);
  24.             if (expirationDate != ExpirationDateText)
  25.             {
  26.                 ExpirationDateText = expirationDate;
  27.                 ha*** pirationDateChanged = true;
  28.             }


  29.             if (!string.IsNullOrEmpty(values[SubmitButtonName]))
  30.                 Page.RegisterRequiresRaiseEvent(this);

  31.             return ha * **pirationDateChanged ||
  32.                 hasCreditCardNoChanged ||
  33.                 hasPaymentMethodChanged ||
  34.                 hasCardholderNameChanged;

  35.         }

 

     这样,我们整个控件就写完了,不知道大家懂了没:有问题回复!完整代码如下:

 

  1. using System;
  2.  using System.Collections.Generic;
  3.  using System.Text;
  4.  using System.Web;
  5.  using System.Web.UI;
  6.  using System.Web.UI.WebControls;
  7.  using System.Collections ;

  8.  using System.Collections.Specialized ;

  9.  namespace CreditCardForm
  10.  {
  11.      public class CreditCardForm6:CreditCardForm5 ,IPostBackEventHandler,IPostBackDataHandler
  12.      {
  13.          #region override name
  14.          protected override string PaymentMethodListName
  15.          {
  16.              get
  17.              {
  18.                  return this.UniqueID + ":PaymentMethod";
  19.              }
  20.          }

  21.          protected override string CreditCardNoTextName
  22.          {
  23.              get
  24.              {
  25.                  return this.UniqueID + ":CreditCardNo";
  26.              }
  27.          }

  28.          protected override string CardholderNameTextName
  29.          {
  30.              get
  31.              {
  32.                  return this.UniqueID + ":CardholderName";
  33.              }
  34.          }

  35.          protected override string MonthListName
  36.          {
  37.              get
  38.              {
  39.                  return this.UniqueID +":Month";
  40.              }
  41.          }

  42.          protected override string YearListName
  43.          {
  44.              get
  45.              {
  46.                  return this.UniqueID + ":Year";
  47.              }
  48.          }

  49.          protected override string SubmitButtonName
  50.          {
  51.              get
  52.              {
  53.                  return this.UniqueID ;
  54.              }
  55.          }
  56.          #endregion
  57.          #region prorerty

  58.          public string PaymentMethodText
  59.          {
  60.              get
  61.              {
  62.                  return ViewState["PaymentMethod"] != null ? (string)ViewState["PaymentMethod"] : string.Empty ;
  63.              }
  64.              set
  65.              {
  66.                  ViewState["PaymentMethod"] = value;
  67.              }
  68.          }


  69.          public string CreditCardNoText
  70.          {
  71.              get
  72.              {
  73.                  return ViewState["CreditCardNo"] != null ? (string)ViewState["CreditCardNo"] : string.Empty;
  74.              }
  75.              set
  76.              {
  77.                  ViewState["CreditCardNo"] = value;
  78.              }
  79.          }

  80.          public string CardholderNameText
  81.          {
  82.              get
  83.              {
  84.                  return ViewState["CardholderName"] != null ? (string)ViewState["CardholderName"] : string.Empty;
  85.              }
  86.              set
  87.              {
  88.                  ViewState["CardholderName"] = value;
  89.              }
  90.          }

  91.          public DateTime ExpirationDateText
  92.          {
  93.              get
  94.              {
  95.                  return ViewState["ExpirationDate"] != null ? (DateTime)ViewState["ExpirationDate"] : DateTime.Now;
  96.              }
  97.              set
  98.              {
  99.                  ViewState["ExpirationDate"] = value;
  100.              }
  101.          }


  102.          #endregion

  103.          #region events
  104.          private static object ValidateCreditCardFormKey = new object();
  105.          public event ValidateCreditCardFormEventHandler ValidateCreditCardForm
  106.          {
  107.              add
  108.              {
  109.                  Events.AddHandler(ValidateCreditCardFormKey, value);
  110.              }
  111.              remove
  112.              {
  113.                  Events.RemoveHandler(ValidateCreditCardFormKey, value);
  114.              }
  115.          }

  116.         
  117.          protected void OnValidateCreditCardForm(ValidateCreditCardFormEventArgs args)
  118.          {
  119.              ValidateCreditCardFormEventHandler handler = Events[ValidateCreditCardFormKey]
  120.                                                                          as ValidateCreditCardFormEventHandler;
  121.              if (handler != null)
  122.                  handler(this, args);
  123.          }

  124.          #endregion
  125.          void IPostBackEventHandler.RaisePostBackEvent(string args)
  126.          {
  127.              ValidateCreditCardFormEventArgs ve = new ValidateCreditCardFormEventArgs(
  128.                  PaymentMethodText, CreditCardNoText, CardholderNameText, ExpirationDateText);

  129.              OnValidateCreditCardForm(ve);
  130.          }

  131.          private bool hasPaymentMethodChanged;
  132.          private bool hasCreditCardNoChanged;
  133.          private bool hasCardholderNameChanged;
  134.          private bool ha***pirationDateChanged;

  135.          bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection values)
  136.          {
  137.              string paymentMethod = values[PaymentMethodListName] == "0" ? "Master" : "Visa";
  138.              if (paymentMethod != PaymentMethodText)
  139.              {
  140.                  PaymentMethod = paymentMethod;
  141.                  hasPaymentMethodChanged = true;
  142.              }

  143.              string creditCardNo = values[CreditCardNoTextName];
  144.              if (creditCardNo != CreditCardNoText)
  145.              {
  146.                  CreditCardNoText = creditCardNo;
  147.                  hasCreditCardNoChanged = true;
  148.              }

  149.              string cardholderName = values[CardholderNameTextName];
  150.              if (cardholderName != CardholderNameText)
  151.              {
  152.                  CardholderNameText = cardholderName;
  153.                  hasCardholderNameChanged = true;
  154.              }

  155.              int month = int.Parse(values[MonthListName]);
  156.              int year=int.Parse (values [YearListName ]);
  157.              DateTime expirationDate=new DateTime (year ,month,10);
  158.              if(expirationDate !=ExpirationDateText )
  159.              {
  160.                  ExpirationDateText =expirationDate ;
  161.                  ha***pirationDateChanged =true ;
  162.              }


  163.              if(!string.IsNullOrEmpty (values [SubmitButtonName ]))
  164.                  Page.RegisterRequiresRaiseEvent (this);

  165.              return ha***pirationDateChanged||
  166.                  hasCreditCardNoChanged ||
  167.                  hasPaymentMethodChanged ||
  168.                  hasCardholderNameChanged ;

  169.          }

  170.          void IPostBackDataHandler.RaisePostDataChangedEvent()
  171.          {
  172.              bool hasChanged;
  173.              hasChanged = hasCardholderNameChanged ||
  174.                  hasCreditCardNoChanged ||
  175.                  hasPaymentMethodChanged ||
  176.                  ha***pirationDateChanged;

  177.              if (hasChanged)
  178.              {

  179.                  ValidateCreditCardFormEventArgs args = new ValidateCreditCardFormEventArgs(
  180.                      PaymentMethod, CreditCardNoText, CardholderNameText, ExpirationDateText);

  181.                  OnValidateCreditCardForm(args);
  182.              }
  183.          }

  184.      }
  185.  }
阅读(938) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~