2011-11-18 37 views
6

Tôi có chức năng, void Validate(), có chứa tất cả logic xác thực của tôi cho một cửa sổ.Triển khai một trình xử lý sự kiện cho nhiều điều khiển với các đại biểu xử lý sự kiện khác nhau

Tôi không thể đăng ký điều này như một trình xử lý sự kiện vì nó không chấp nhận các tham số được yêu cầu bởi các đại biểu xử lý sự kiện. Ngoài ra các loại điều khiển khác nhau có chữ ký khác nhau vì vậy tôi không thể chỉ có Validate khớp một chữ ký trong khi bỏ qua nội dung của chúng.

Dưới đây là một ví dụ nhỏ về những gì tôi đã thiết lập

txt1.TextChanged += Validate_TextChange; 
    password1.PasswordChanged += Validate_RoutedEvent; 
    txt2.TextChanged += Validate_TextChange; 

    txt3.TextChanged += Validate_TextChange; 
    password2.PasswordChanged += Validate_RoutedEvent; 
    txt4.TextChanged += Validate_TextChange; 


void Validate_RoutedEvent(object sender, RoutedEventArgs e) 
{ 
    ValidateOptions(); 
} 

void Validate_TextChange(object sender, TextChangedEventArgs e) 
{ 
    ValidateOptions(); 
} 

public void ValidateOptions() 
{ 
    //Actual validation here 
} 

này chỉ cho thấy 2 ví dụ, nhiều điều khiển có thể có nhiều hơn chữ ký. Có cách nào tốt hơn để có được tất cả các trình xử lý sự kiện để gọi một hàm trong một trường hợp mà tôi không quan tâm về các đối số được truyền?


EDIT: Tôi thích tùy chọn do Jon đề xuất thêm thông số và chỉ đơn giản bỏ qua chúng. Điều đó giải quyết hầu hết vấn đề nhưng bất cứ khi nào tôi muốn gọi hàm này trực tiếp, chẳng hạn như để kích hoạt xác nhận theo cách thủ công, thì tôi phải bao gồm các đối số giả để thỏa mãn trình biên dịch. ValidateOptions (this, new EventArgs())

Đề xuất Dan thực hiện, sử dụng các chức năng ẩn danh, sẽ xử lý việc này nhưng không sạch sẽ khi kết hợp các trình xử lý sự kiện. Có vẻ như một trong hai giải pháp cho phép bạn đăng ký một chức năng như một trình xử lý sự kiện trong khi bỏ qua chữ ký trong khi vẫn giữ khả năng gọi hàm mà không tạo đối số giả nhưng có nhiều cách để có được khá gần.


EDIT:

Dưới đây là ví dụ cập nhật việc thực hiện giải pháp Jon cho generic xử lý sự kiện nhưng giữ một chức năng 0 Thông số có thể được gọi trực tiếp

txt1.TextChanged += ValidationEvent; 
password1.PasswordChanged += ValidationEvent; 
txt2.TextChanged += ValidationEvent; 

txt3.TextChanged += ValidationEvent; 
password2.PasswordChanged += ValidationEvent; 
txt4.TextChanged += ValidationEvent; 


//Single event handler accepting EventArgs, which is the base class 
//for all more-specific event classes 
void ValidationEvent(object sender, EventArgs e) 
{ 
    //Ignores arguments and calls 0 argument ValidateOptions 
    ValidateOptions(); 
} 

//0 argument function that performs actual validation and can be called 
//directly from other functions without the need to pass in a fake sender 
//and eventargs parameter 
public void ValidateOptions() 
{ 
    //Actual validation here 
} 

Trả lời

6

Bạn thể có một phương pháp duy nhất mà bỏ qua các thông số:

public void ValidateOptions(object sender, EventArgs e) 
{ 
} 

Trình biên dịch sẽ cho phép một sự chuyển đổi từ nhóm ValidateOptions phương pháp để bất kỳ loại đại biểu sau đây mô hình sự kiện bình thường như vậy tham số đầu tiên là sender và tham số thứ hai là một số loại bắt nguồn từ EventArgs.

+0

Ngay cả những chữ ký 'void (đối tượng, đối tượng) 'sẽ làm việc thực sự. –

+2

@ H.B.True: Tôi muốn làm cho nó rõ ràng nó có cho xử lý sự kiện mặc dù :) –

+0

@ Jon Tôi thích điều này, và nó đã làm việc, nhưng sau đó tôi nhận ra rằng tôi bỏ qua một phần của trường hợp sử dụng trong câu hỏi ban đầu của tôi (cập nhật) . Một lý do mà hàm Validate() đã không làm điều này là vì tôi muốn gọi nó để buộc xác nhận từ các hàm khác và với cách tiếp cận này, tôi đơn giản hóa việc sử dụng trình xử lý sự kiện nhưng phải sử dụng các giá trị giả khi gọi trực tiếp. – Eric

5

Bạn có thể sử dụng biểu thức lambda để giảm số lượng mã bạn viết cho trình bao bọc, mặc dù, đằng sau hậu trường, nó vẫn tạo ra các phương thức trình bao bọc để loại bỏ các tham số.

txt3.TextChanged += (s,e) => ValidateOptions(); 
password2.PasswordChanged += (s,e) => ValidateOptions(); 
txt4.TextChanged += (s,e) => ValidateOptions(); 
0

xử lý này cung cấp một callback duy nhất cho điều khiển khuôn khổ và lập luận 'e' được bảo tồn phục vụ tiêu dùng ...

private static void EventHandlerSink(object sender, dynamic e) 
    { 

    } 
+0

Không cần sử dụng 'dynamic' khi tất cả các đối số sự kiện được thừa kế từ' EventArgs', bạn chỉ mất giao diện nhỏ mà bạn đã để lại khi chuyển nó sang đó. –

Các vấn đề liên quan