2013-07-19 41 views
14

Đây là một câu hỏi rất đơn giản, nhưng tôi đã tự hỏi liệu có ai đó có thể giải thích dòng thứ 4 thực sự đang làm gì không? do đó, dòng đầu tiên đưa ra một sự kiện cho trình xử lý. Tôi không thực sự biết trong trường hợp xử lý sẽ trả về null hoặc những gì dòng cuối cùng không.PropertyChangedEventHandler hoạt động như thế nào?

Khi bạn vượt qua trình xử lý đối tượng của bạn và thuộc tính nào đã thay đổi, nó sẽ làm gì với chúng?

PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event 

if (handler != null) 
{ 
    handler(this, new PropertyChangedEventArgs(name)); 
} 

Tôi giả sử tôi đã sử dụng điều này để có được điều này code nhưng tôi muốn hiểu những gì nó đang làm đầy đủ.

+0

Không có ngữ cảnh khó nói.Bạn đang sử dụng khung công tác nào? Đó không phải là một phần của BCL, có lẽ một số khung MVVM mà bạn đang kiểm tra/sử dụng. – Will

+0

Điều đó không có vẻ gì đặc biệt đối với 'PropertyChangedEventHandler'. Đó chỉ là cách trình xử lý hoạt động. –

+0

Nhận xét của Will là vô nghĩa. Điều này được gắn thẻ WPF. PropertyChangedEventHandler nằm trong System.ComponentModel. Không có những thứ như khung MVVM - MVVM là một mẫu kiến ​​trúc hữu ích nhưng không cần thiết cho WPF. Dù sao, câu hỏi này là về cách xử lý sự kiện làm việc trong C# và câu trả lời không phải là cụ thể cho bất kỳ sự kiện hoặc khuôn khổ cụ thể. –

Trả lời

35

Nếu bạn chỉ cần làm:

PropertyChanged(this, new PropertyChangedEventArgs(name)) 

bạn sẽ nhận được một NullReferenceException nếu không có ai đã đăng ký sự kiện PropertyChanged. Để chống lại điều này, bạn thêm một kiểm tra null:

if(PropertyChanged != null) 
{ 
    PropertyChanged(this, new PropertyChangedEventArgs(name)) 
} 

Bây giờ, nếu bạn đang sử dụng đa luồng ai đó có thể huỷ đăng ký giữa việc kiểm tra null và sự kêu gọi của sự kiện, vì vậy bạn vẫn có thể nhận được một NullReferenceException. Để xử lý mà chúng ta sao chép các xử lý sự kiện cho một biến tạm thời

PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
    { 
    handler(this, new PropertyChangedEventArgs(name)); 
    } 

Bây giờ nếu ai đó sẽ hủy đăng ký từ sự kiện biến tạm thời của chúng tôi handler vẫn sẽ trỏ đến các chức năng cũ và mã này ngay bây giờ không có cách nào ném một NullReferenceException.

Thông thường bạn sẽ thấy mọi người sử dụng từ khóa var thay vào đó, điều này khiến bạn không cần nhập loại đầy đủ của biến tạm thời, đây là biểu mẫu bạn sẽ thấy thường xuyên nhất trong mã.

var handler = PropertyChanged; 
    if (handler != null) 
    { 
    handler(this, new PropertyChangedEventArgs(name)); 
    } 
+0

Trong điều kiện chủng tộc, sẽ không sao chép trình xử lý sau đó gọi một hàm mà ai đó vừa chỉ định sẽ không còn được gọi? Đó có phải chỉ là cách thức kinh doanh được chấp nhận hay có cái gì đó mà tôi đang thiếu? –

+1

@ZachMierzejewski Vâng, đó là hành vi mong đợi. Đó là trách nhiệm của người đăng ký để biết rằng mặc dù đã hủy đăng ký nếu trong tình huống đa luồng, bạn vẫn có thể nhận được cuộc gọi cuối cùng cho phương thức. Tất cả các sự kiện của các lớp được xây dựng trong .NET hoạt động với mẫu này. –

6

handler có thể rỗng nếu không có trình xử lý là subscribed đến event, dòng thứ tư tăng sự kiện cho tên thuộc tính được cung cấp (thực thi tất cả trình xử lý đã đăng ký).

Thông thường khung công tác WPF sẽ đăng ký PropertyChanged khi bạn sử dụng các ràng buộc, do đó, nó có thể cập nhật ràng buộc khi thay đổi thuộc tính bị ràng buộc.

7

PropertyChanged là sự kiện đã được tuyên bố như thế này, theo định nghĩa của nó trong giao diện:

public event PropertyChangedEventHandler PropertyChanged; 

Events được định nghĩa như thế là thực sự là một cú pháp đường cho một danh sách các xử lý sự kiện bạn có thể thêm một đại biểu (đó là một tham chiếu đến một chức năng) bằng cách đăng ký, hoặc loại bỏ một đại biểu bằng cách hủy đăng ký.

Bây giờ, khi bạn gọi một sự kiện, tức là PropertyChanged(...), thì điều xảy ra bên trong là mọi đại biểu trong danh sách nội bộ đó được gọi riêng với thông số. Điều này sẽ cho tất cả những người đăng ký sự kiện của bạn biết rằng sự kiện đã xảy ra.

Bây giờ, lý do cho toàn bộ điều với biến số handler là, PropertyChanged có thể là rỗng. Nếu không có gì đăng ký với nó, sau đó gọi sự kiện (hoặc đúng hơn là danh sách trình xử lý sự kiện) sẽ không hoạt động, vì vậy đây chỉ là một cách để đảm bảo rằng bạn thực sự có thể thực thi trình xử lý.

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