Truyền dữ liệu giữa 2 form bằng delegate và event

Delegate là một khái niệm không xa lạ gì trong c# và nó cũng có rất nhiều công dụng. Trong nội dung bài viết này, mình xin giới thiệu một công dụng vô cùng hữu dụng của delegate, đó là truyền dữ liệu.

Chú ý

Để dễ dàng áp dụng các hình thức truyền dữ liệu, mình tạm gọi cách truyền dữ liệu bằng delegate là truyền ngược và cách truyền dữ liệu bằng Properties; Static variables; Constructor là cách truyền xuôi.

Để dễ hình dung, bạn hãy tưởng như sau:

  • Cách truyền xuôi (1 chiều): A (bản thân bạn) đưa 1 món đồ cho B (bạn của bạn). Tức là A truyền cho B 1 cái gì đó.
  • Cách truyền ngược (2 chiều): A muốn lấy 1 món đồ từ B, A bảo B: "B ơi, mày đưa giùm tao cái bút!". Sau đó, B mới đưa cây bút cho A. Tức là A hoàn thành việc bằng cách nhờ B.

Nếu có vẻ khó hiểu (thực ra mình cũng đưa ra ví dụ tượng trưng), các bạn hãy bắt đầu với ví dụ sau đây.

Ví dụ

pass data by delegate

Khi click vào button Please login ở Form1, Form2 sẽ xuất hiện. Nếu nhập đầy đủ thông tin ở Form2 và click OK, Username và Password sẽ được truyền ngược lại Form1 và hiển thị ra Info.

Code

Trước hết là bắt sự kiện click của 2 button ở Form2

Chú ý

Dòng 1: khai báo 1 delegate có kiểu là void, tên là Login, nhận 2 tham số là string username và string password, 2 tham số này sẽ được truyền đi qua Form1.

 [phương thức truy cập]  delegate [kiểu trả về] [Tên] [<Danh sách tham số (optional)>];

Dòng 2: khai báo 1 event (sự kiện), sự kiện này có kiểu là delegate Login, tên là LoginEvent, sự kiện sẽ được gọi ở Form2 và phát sinh ở Form1.

[phương thức truy cập] event [kiểu delegate] [Tên];

Và trong sự kiện của button OK, thêm đoạn code sau:

Chú ý

  • Dòng 6: Kiểm tra đã nhập đầy đủ Username và Password chưa, nếu chưa thì thông báo ra màn hình và thoát khỏi sự kiện.
  • Dòng 13: Kiểm tra sự kiện LoginEvent có khác null không, nếu khác null tức là nó đã được gọi ở đâu đó (sự kiện này sẽ được gọi ở Form1), thì lúc đó mới truyền 2 tham số username và password vào sự kiện này.
  • Điều kiện else là kiểm tra nếu sự kiện LoginEvent chưa được gọi.

Ở form 1, bắt sự kiện click ở button Please login và thêm đoạn code sau, chú ý cách gọi event từ Form2

fire event

Cách gọi sự kiện hoàn toàn như các bạn gọi sự kiện click của button (***), sau khi gõ += thì sẽ có 1 notification để hướng dẫn các bạn chỉ cần bấm Tab để thêm sự kiện, sau đó bấm Tab 1 lần nữa để tự động phát sinh code. Tóm lại, sau khi gõ +=, các bạn bấm Tab 2 lần liên tiếp.

(***) Có nhiều cách để gọi sự kiện của 1 control, các bạn có thể double click ở tab Events trong giao diện của Visual Studio, code sẽ tự động phát sinh và thêm vào, hoặc các bạn cũng có thể tự viết (gọi) sự kiện giống như dòng 19. Bản chất của 2 cách này là giống nhau.

Bổ xung đoạn code như sau:

Phương thức frm2_LoginEvent chính là phương thức xảy ra khi sự kiện LoginEvent được gọi ở Form2, username và password đã được truyền qua Form1, ta chỉ cần hiển thị nó ra label.

Và kết quả

pass data by delegate

Nếu các bạn muốn hiểu kỹ quá trình chạy của chương trình và cách sự kiện được gọi ra sao, hãy thử debug chương trình là sẽ thấy rõ.

Source code

Comments

  1. Tại sao em làm thì cái form 2 nó bật lên 2 lần ạ ?

    ReplyDelete
    Replies
    1. Bạn check xem có chỗ nào gọi show dialog 2 lần không, hoặc gọi 1 sự kiện 2 lần không?

      Delete
  2. chào anh giả sử em muốn xử lý 1 biến ở form 2 lấy dữ liệu từ form 1,,và trả ngược biến đó lại form 1 thì làm s a

    ReplyDelete
  3. vd:form1 có sản phẩm có giá tiên.form 2 nhap vao giá trả trước và so tháng.trả về form 1 so tháng cần trả và số tiền phải trả mỗi tháng

    ReplyDelete
    Replies
    1. Trên chỉ là 1 ví dụ cho ứng dụng của delegate. Với nhu cầu của bạn, bạn có thể tạo 2 Property ở 2 form và gọi qua lại lẫn nhau là được.

      Delete
  4. Form1: txtUser,txtPass,btnDN
    Form2: được mở từ form main, có textbox1 và btnThêm
    Khi nhấp btnThêm thì lấy txtUser truyền vào textbox1

    ReplyDelete
    Replies
    1. Hi @thanh, đây là 1 câu hỏi hay gì vậy bạn :))

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. ở đây mình có thể sử dụng public property và "pass" bằng reference (tham chiếu), cụ thể là

      // Form1.cs

      ```cs
      public Student MyStudent { get; set; }

      public void ShowForm2()
      {
      // Dĩ nhiên ở Form2 cũng phải có 1 property SelectedStudent kiểu là Student
      Form2.SelectedStudent = MyStudent; // reference
      // show form 2
      }
      ```

      khi đó bạn làm gì SelectedStudent ở Form2 thì Form1 cũng thay đổi theo (vì bản chất 2 cái là 1)

      Delete
    2. vd em truyền image1 từ form1 qua form 2 và form 2 sẽ chỉnh sửa ảnh này và tách ra thành image 2 và image 3, vậy vẫn phải dùng delegate chứ nhỉ. Nhưng vì form 2 em ẩn đi nên sau khi ra được image 2, 3 em muốn nó tự đổ qua form 1 luôn ý.

      Delete
    3. vậy hành động "ẩn form 2" xảy ra lúc nào? bạn có thể truyền ngược lại lúc đó cũng được

      Delete
    4. form 2 luôn luôn ẩn, nó vẫn hoạt động nhưng chỉ là mình ko hiện form lên thôi.

      Delete
    5. form 2 luôn luôn ẩn, nó vẫn hoạt động nhưng chỉ là em ko hiện form lên thôi.

      Delete
  6. This comment has been removed by the author.

    ReplyDelete

Post a Comment

Popular posts from this blog

Gỡ bộ Visual Studio ra khỏi máy tính

Căn giữa thẻ div trong thẻ div