วันอังคารที่ 13 พฤศจิกายน พ.ศ. 2555

Delegate & Event ใน C# เพื่อใช้ในการรับส่งค่าระหว่าง From สามารถนำไปใช้ได้


delegate ซึ่งแปลตรงตัวก็คือ 'ตัวแทน' โดยการทำงานของมันก็ทำหน้าที่เป็นตัวแทนของ method 
ลักษณะการใช้งาน Delegate ซึ่งโดยปกติการเรียกใช้ method นั้นเราต้องระบุชื่อ method ที่เราต้องการใช้งาน แต่แนวคิดในการโปรแกรมแบบ Delegate นั้นต่างออกไป โดยแทนที่เราจะเรียกไปที่ methodที่เราต้องการ ตรงๆแต่กลับเรียกผ่าน Delegate แทน   ซึ่ง Delegate ก็คือตัวแทน method ที่เราต้องการนั่นเอง  โดยผู้เรียก delegate จะไม่รับรู้ว่า method จริงอยู่ที่ส่วนใดของโปรแกรม แค่คิดว่าถ้าเรียกผ่าน Delegate แล้ว Delegate จะต้องมีหน้าที่ทำงานได้ตามที่ผู้เรียกต้องการเท่า
Ex:    ผู้เรียก -------------------------> Delegate -------------------------> Class1.fnc();
การประกาศ Delegate  
delegate void Mydelegate ();
จุดประสงค์ของประโยคด้านบนคือ ประกาศDelegate type ชื่อ Mydelegate ซึ่งไม่มี argument และมี return type เป็น void

 เบื้องหลังการทำงานนั้น compiler จะสร้าง metadata และ class ที่สืบทอดมาจาก MulticastDelegatให้อย่างอัตโนมัติ ซึ่งสามารถแสดงดัง psuedocode 
class Mydelegate : MulticastDelegate
{      
   public Mydelegate(object obj, int ptr)
   { }
   public void Invoke()
   { }
}


เรามาเริ่มเขียน Code  ในการรับส่งข้อมูล  โดยใช้  delegate  เป็น ตัวแทนของ Method By Event กันครับ 
จาก  Flow การทำงานดังกล่าว 
     ผู้เรียก -------------------------> Delegate -------------------------> Class1.fnc();
เราจะทำการสร้าง  From มา 2 From   โดย
ผู้เรียก  ==> FrmSale.cs   (หน้าจอขายเพื่อแสดงรายการสินค้า)
ผู้ถูกเรียก ===> Frm_Find.cs (หน้าจอที่แสดงรายการสินค้า เพื่อ Set กลับมาที่หน้าจอขาย)
Delegate  ===> จะเป็น Object  ที่อยู่ในหน้าจอ   Frm_Find.cs
Class1.fnc() ==>จะเป็น Class ที่ Delegate  Pass  ค่าเข้าไปให้  และ ถูก   FrmSale.cs นำข้อมูลกลับผ่าน Event 

เอาละ  เรามาลอง Code ในแต่ละส่วนกัน  มาเริ่มที่   Frm_Find.cs  ก่อนนะครับ 


CODE#:  Frm_Find.cs 


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TransForm
{
       public partial class Frm_Find : Form
      {
          // IdentityProduct   คือ Class (Class1.fnc())  ที่ใช้  Delegate  เป็นตัวแทน 
           public delegate void IdentityReturnHandler(object sender, IdentityProduct e);
          // Identitydata เป็น Event ของ Form(Frm_Find)  เพื่อที่จะ Pass Valuse กลับไปยังผู้ที่เรียก
           public event IdentityReturnHandler Identitydata;       

         /// 
         ///  ======> ในส่วนนี้เป็นแค่ตัวอย่างนะครับ  ที่จริงต้อง Return กลับเป็น  DataRow หรือ DataSet
         /// 
         /// 
         /// 
        private void btn_OK_Click(object sender, EventArgs e)
        {
            try
             {
                    string  ls_Name  = txt_Name.Text;
                    Decimal  ld_Price  = Convert.ToDecimal(txt_Price.Text)   
//สังเกตุIdentityProduct ให่ดีนะครับมันจะถูกสร้างเป็น Type Event ใน   ตัว delegate 
                    // เพราะเวลาที่ตัวเรียกใช้  จะเรียกผ่าน Event 
                    IdentityProduct arge = new IdentityProduct( ls_Name, ld_Price);  // ส่งค่าไปยัง Class   IdentityProduct  
                    Identitydata(this, arge);
                    this.Dispose();
             }
            catch { }
         } 
}

   /// 
    ///  เป็น CLASS ที่ทำการส่งค่ากลับไปให้ From Sale โดยที่ตัว Delegate  เป็นตัวแทน โดบ Return  กลับผ่าน Event
    /// 
    public class IdentityProduct : System.EventArgs
    {
        string  ls_Name  = String.Emtry;
        Decimal  ld_Price  =0;        
       
        // เป็น Constructure ของ Class  รับค่าได้อย่างเดียว
        public IdentityProduct( string  Name ,Decimal  Price)
        {
             ls_Name  = Name;
             ld_Price   = Price;
        }


       // เป็น Property ที่จะทำการ Return กลับไปโดย Event 
        public string  Name
        {
            get { return ls_Name; }
        }

        public Decimal  PRICEPRODUCT
        {
            get { return ld_Price; }
        }
    }    
}


CODE#:  FrmSale.cs

มาดูตอนที่เรียกครับ สร้าง From มา 1 From จากนั้นก้อสร้าง ปุ่ม


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TransForm
{
   public partial class FrmSale : Form
    {
     private void btn_Search_Click(object sender, EventArgs e)
        {
              Frm_Find _F = new Frm_Find();
             // บรรทัดล่างนี้จะเป็นการเรียกใช้งานผ่าน Event ที่อยู่ใน From   Frm_Find
            _F.Identitydata+=new Frm_Find.IdentityReturnHandler(_F_Identitydatarow);
            _F.ShowDialog();
        } 
// Methodนี้จะถูกCreate ขึ้นมาตอนที่เราเรียกใช้  Event _F.Identitydata+=new Frm_Find.IdentityReturnHandler   (_F_Identitydatarow);
         void _F_Identitydata(object sender, IdentityProduct e)
        { 
             //  จากนั้น ตัวแปลจาก From ก็ ถูกส่งผ่าน Class  IdentityProduct   ใน Event e  เพราะตอนที่เรา  delegate  เราให้มันเป็น Event 
             Txt_Name.Text  = e.Name;
             Txt_Price.Text   = e.PRICEPRODUCT.Tostring();
        }
    }
}

Credit: WINCOMMON