Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 5 123 ... CuốiCuối
Kết quả 1 đến 10 của 42
  1. #1

    Cách dùng delegate trong lập trình C#

    Chào các bạn, nay mình xin làm một bài về tạo một delegate trong C#.
    - Delegate là gì? Nó có nghĩa là “ủy quyền”, hay là “ủy thác” nó tựa tựa như là con trỏ hàm trong C/C++ vậy.
    - Dùng nó khi mà ta đang ở chổ này, mà cần làm 1 việc gì đó ở chổ khác. Ví dụ đơn giản thế này. Bạn đang ở nhà của nhỏ bạn của bạn, nhỏ đó nhờ bạn sửa bài đồ án cuối kỳ cho nhỏ đó, bạn biết trước được như vậy nên trước khi đi bạn đưa chìa khóa phòng cho nhỏ em gái của mình nhờ nó ”mày cầm chìa khóa phòng anh nè”, xong tự dưng máy của nhỏ bạn đó bị cháy nguồn, giờ phải về phòng bạn làm bài, phòng bạn hết sức là lầy, nhiều rác, tô mì ăn cả tuần chưa rửa [IMG]images/smilies/tongue.png[/IMG]. Bạn alo gọi nhỏ em, “mày qua dẹp phòng cho anh đi, nhỏ bạn mà thây lầy quá nó chán anh thì toi [IMG]images/smilies/biggrin.png[/IMG]”. trong trường hợp này bạn không thể nào tự dẹp phòng mình được, phải nhờ con em nó làm cho vậy bạn đã ủy quyền cho nó 1 hành động nào đó có, bạn không biết là hành động nào trước để mà chuẩn bị, lúc này bạn phải nhờ người khác làm giùm.
    - Cũng tương tự như vậy trong lập trình, bạn không thể nào biết được trước trong một số trường hợp là phải tạo thuộc tính nào cho đối tượng của mình (ví dụ bạn tạo 1 usercontrol bạn không thể nào biết được hành động nào ứng với event click chuột vào đó, giả sử click chuột vào đó ở formA bạn cho ra 1 MessageBox, cũng event click chuột lên cái Usercontrol đó ở form khác thì bạn Set cái đoạn text của Usercontrol đó lên form đó).
    - Nói dài dòng quá [IMG]images/smilies/tongue.png[/IMG] giờ ví dụ cho các bạn luôn:
    Ví dụ khá đơn giản và đã post lên 4rum 1 lần rồi, nay mình post lại 1 lần nữa.
    Trên form1 có 2 lable, và 2 button, click vào button1 show form2 lên, form2 có 2 text box, 2textbox của form2 gõ gì, thì 2 lable của form1 show lên cái đó.
    Đây là hình của chương trình lúc chưa run.


    Bên form 1 bạn code như sau:


    Mã:
    public partial class Form1 : Form{public Form1(){InitializeComponent();} public void GetValue(String str1, String str2){// khai báo 1 hàm với 2 tham số đầu vào là str1, và str2 nó sẽ đưa dữ liệu vào 2 lable label1.Text = str1;label2.Text = str2;}private void button1_Click(object sender, EventArgs e){  Form2 f2 = new Form2();// ké thằng GetValue của form1 vào form2   f2.MyGetData = new Form2.GetString(GetValue);  f2.Show(); }             private void button2_Click(object sender, EventArgs e)          {              Application.Exit();          }      }
    Bên form 2 bạn code như sau:



    Mã:
      public partial class Form2 : Form      {          public Form2()          {              InitializeComponent();          }     // khai báo 1 hàm delegate          public delegate void GetString(String MyString1, String MyString2);  // khai báo 1 kiểu hàm delegate          public GetString MyGetData;                   private void button1_Click(object sender, EventArgs e)          {                            this.Close();          }                    private void textBox1_TextChanged(object sender, EventArgs e)          {              if (MyGetData != null)              {// tại đây gọi nó                  MyGetData(textBox1.Text, textBox2.Text);              }           }             private void textBox2_TextChanged(object sender, EventArgs e)          {              if (MyGetData != null)              {// tại đây cũng gọi nó                  MyGetData(textBox1.Text, textBox2.Text);              }           }      }
    Đây là kết quả.

  2. #2
    Mạn phép góp chút ý kiền nha các bạn !

    - Theo mình hiểu thì delgate là cơ chế tự động gọi lại 1 hoặc nhiều method. Về hình thức, Delegate là 1 khuôn mẫu mà các method đc gọi lại thông qua Delegate phải theo. VD ta có 1 delegate
    public delegate void myDelegate(String, Int16);
    Các method muốn đc gọi thông qua phải theo khuôn mẫu mà Delegate đã đặt ra (bao gồm giá trị trả về và danh sách tham số - ko bao gồm tên và modifier). VD:
    public void methodToCallBack(String str, Int16 n) {}
    Về bản chất, Delegate là 1 class, kế thừa từ MulticastDelegate, nên bạn có thể khai báo 1 Delegate ở bất cứ đâu bạn có thể khai báo 1 class.

    - Các method đc gọi lại thông qua Delegate có thể là 1 instance method, cũng có thể là 1 class method.VD:

    Mã:
    class MethodClass{    public void InstanceMethod((String str, Int16 n)  {} // (1)    static void ClassMethod((String str, Int16 n)  {} //(2)}
    - Delegate cũng có thể đc xem là 1 trình bọc (wrapper quanh 1 hoặc nhìu method sẽ đc gọi lạ). Trong 1 class nào đó bạn có thể khai báo delegate như sau:
    - Với method (1) bạn tạo 1 wrapper đến method như sau :

    Mã:
    MethodClass onj = new MethodClass ();myDelegate monoDelegate = new myDelegate(obj.InstanceMethod);
    - Với method (2) bạn tạo 1 wrapper đến method như sau :

    Mã:
    myDelegate monoDelegate = new myDelegate(MethodClass.ClassMethod);
    Hoặc có thể để 1 Delegate bao quanh nhiều method tương tự như sau:

    Mã:
    myDelegate delegate = null;multiDelegate += new myDelegate(obj.InstanceMethod);multiDelegate += new myDelegate(MethodClass.ClassMethod);
    - Khi 1 Delegate đc tạo để bao nhiều method thì khi đc gọi, lần lượt các method đã đc bao sẽ đc gọi.
    VD ta có lệnh gọi :
    mutiDelegate(“abc”, 10);
    thì lần lượt các method InstanceMethod, ClassMethod sẽ đc gọi với cùng tham số đa truyền vào lệnh gọi đến Delegate (ở đây là 1 String “abc” và 1 Int16 10)

    - Theo mình biết thì Delegate thường dùng để gọi lại các method từ 1 method bên khác, thường dùng để tạo các hàm xử lý sự kiện như trong VD của bạn chủ topic

    Chút ít ý kiến. Có j sai sót mọng nhận đc ý kiến của các bạn !

    Lưu ý để code vào tag code

  3. #3
    Mình thì lại thấy dùng Delegate để truyền dữ liệu như trên quá là rườm rà.
    Bây giờ ví dụ trên form mình lại có thêm những đối tượng khác, chẳng lẽ cứ muốn truyền dữ liệu cho cái nào thì phải tạo một cái delegate tương ứng hay sao?

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Mình thì lại thấy dùng Delegate để truyền dữ liệu như trên quá là rườm rà.
    Bây giờ ví dụ trên form mình lại có thêm những đối tượng khác, chẳng lẽ cứ muốn truyền dữ liệu cho cái nào thì phải tạo một cái delegate tương ứng hay sao?
    hì. đúng như anhtuyenbk nói [IMG]images/smilies/smile.png[/IMG]
    nó hơi rườm rà nhưng nó khỏe hơn trong 1 số trường hợp

    như nếu dùng UserControl thì mình thấy trong 1 số trường hợp, chúng ta dùng delegate thì code sẽ dễ hơn, uyển chuyển hơn... rất nhiều so với dùng properties. [IMG]images/smilies/smile.png[/IMG]

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Ngoài sử dụng delegate và properties thì vẫn còn 1 số cách để truyền dữ liệu giữa 2 form.Tùy trường hợp mà ta sử dụng thôi.Tham khảo các cách khác ở đây

    Mã:
    http://www.codeproject.com/KB/cs/pass_data_between_forms.aspx

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    chắc zkday2686 muốn nêu ví dụ đó mà. Chứ thường người ta dùng Delegate để thiết kế event hoặc dùng cho remoting thôi, chứ truyền dữ liệu như vậy thì mệt thiệt [IMG]images/smilies/smile.png[/IMG]

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Nhanh nhất là truyền thẳng cái đối tượng Form1 vào constructor của Form2.
    Thế là truy xuất thoải mái.

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mã:
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
     public void GetValue(String str1, String str2)
    {// khai báo 1 hàm với 2 tham số đầu vào là str1, và str2 nó sẽ đưa dữ liệu vào 2 lable
     label1.Text = str1;
    label2.Text = str2;
    }
    private void button1_Click(object sender, EventArgs e)
    {
      Form2 f2 = new Form2();
    // ké thằng GetValue của form1 vào form2
       f2.MyGetData = new Form2.GetString(GetValue);
      f2.Show();
     }
       
              private void button2_Click(object sender, EventArgs e)
              {
                  Application.Exit();
              }
          }
    xin hỏi các bạn là tại sao hàm GetValue có tận 2 tham số vậy mà khi khai báo trong new Form2.GetString(GetValue); thì nó không còn tham số nào ,bạn có thể giải thích cho mìinh được không,cảm ơn bạn nhiều

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    tại vì hàm Form2.GetString(...) nhận 1 tham số kiểu delegate. Còn GetValue trong Form2.GetString(GetValue); đóng vai trò là tham số truyền vào thôi chứ không phải là một lời gọi hàm đơn thuần.

    Có lẽ bạn chưa hiểu về Delegate, mình lấy ví dụ thế này cho bạn dễ hiểu nhé.
    Ta có một method FindMax tìm số lớn nhất như sau:

    Mã:
    void int FindMax(int[] myArray);{        int max = myArray[0];         foreach (int i in myArray)        {            if (i > max)                max = i;        }        return max;}
    Nhưng sau này bạn muốn tìm chuỗi lớn nhất thì sao nhỉ, bạn có thể nghĩ tới việc viết 1 hàm FindMax tổng quát cho một mảng array (bao gồm các object):

    Mã:
    void int FindMax(Array myArray)
    nhưng khổ nỗi lại không biết so sánh các object như thế nào, không thể viết objectA > objectB được, vì thế bạn nghĩ tới việc sẽ ủy quyền việc so sánh 2 phần tử cho 1 hàm delegate nào đó, nó sẽ như thế này:

    Mã:
        static object FindMax(Array myArray, CompareHandler compare)    {        object max = myArray.GetValue(0);         foreach (object obj in myArray)        {            if (compare(obj, max) > 0)                max = obj;        }        return max;    }
    và hàm compare là một delegate có dạng CompareHandler . Đó là 1 delegate so sánh 2 phần tử, vì thế nó phải có dạng hàm như sau:
    Mã:
    delegate int CompareHandler(object a, object b);
    Dạng hàm này trả về số int > 0 nếu a = b, < 0 nếu a < b, và > 0 nếu a > b.

    Như vậy là bạn đã làm xong hàm FindMax tìm phần tử lớn nhất trong 1 mảng tổng quát.

    Vậy sau này khi dùng ta chỉ cần định nghĩa 1 hàm compare cho kiểu dữ liệu mảng tương ứng đó thôi.


    Mã:
        static int CompareInt(object a, object b)    {        return (int)a - (int)b;    }    static int CompareString(object a, object b)    {        return ((string)a).CompareTo((string)b);    }     static void Main()    {        CompareHandler compareDelegate = null;         int[] arrInt = { 1, 2, 5, 10, 3, 6 };        compareDelegate = CompareInt;        int maxInt = (int)FindMax(arrInt, compareDelegate);        Console.WriteLine("max = {0}", maxInt);         string[] arrStr = { "1", "2", "5", "10", "3", "6" };        compareDelegate = CompareString;        string maxStr = (string)FindMax(arrStr, compareDelegate);        Console.WriteLine("max = {0}", maxStr);    }

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    cho mình hỏi là mình dùng cái này vào trong việc login được không?
    Nghĩa là khi login xong thì tên người login sẽ được hiển thị trên các form khác ý?

 

 
Trang 1 của 5 123 ... CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •