2011-10-19 8 views
11

Tôi có chức năng cốt lõi được đóng gói trong ViewModelBaseLàm cách nào để đăng ký sự kiện PropertyChanged trong ViewModel của tôi?

Bây giờ tôi muốn xem khi sự kiện PropertyChanged được nâng lên bởi ViewModelBase và hành động trên nó. Ví dụ: khi một thuộc tính đã được thay đổi trên ViewModelBase - tôi muốn thay đổi thuộc tính trên ViewModel

Làm cách nào để đạt được điều này?

public class MaintainGroupViewModel : BaseViewModel<MEMGroup> 
    { 


public abstract class BaseViewModel<T> : NotificationObject, INavigationAware 
     where T : Entity 
    { 
+1

Giao diện 'NotificationObject' của bạn có triển khai giao diện' INotifyPropertyChanged' không? Nếu có, thì đó là đăng ký sự kiện cơ bản. Nếu không thì bạn nên thực hiện 'INotifyPropertyChanged'. –

Trả lời

9

Tôi lo ngại rằng bạn đang có hiệu quả làm một ' ràng buộc thủ công '(xấu) cho một thuộc tính trong một lớp dẫn xuất đến một giá trị trên lớp cơ sở (cũng xấu). Toàn bộ điểm của việc sử dụng thừa kế là lớp dẫn xuất có thể truy cập mọi thứ trong lớp cơ sở. Sử dụng công cụ sửa đổi protected để cho biết mọi thứ chỉ có thể truy cập được đối với các lớp dẫn xuất.

tôi sẽ đề nghị phương pháp này (khả năng) chính xác hơn:

lớp Base:

protected virtual void OnMyValueChanged() { } 

nguồn gốc lớp:

protected override void OnMyValueChanged() { /* respond here */ } 

Thực sự, đăng ký vào một sự kiện trong lớp cơ sở của lớp học mà bạn đang viết chỉ có vẻ cực kỳ lạc hậu - điểm của việc sử dụng thừa kế trong bố cục là gì nếu bạn định tự mình sáng tác? Bạn đang yêu cầu một đối tượng để tự nói với chính mình khi có điều gì đó xảy ra. Một cuộc gọi phương thức là những gì bạn nên sử dụng cho điều đó.

Xét về "khi một thuộc tính được thay đổi trên ViewModelBase - Tôi muốn thay đổi thuộc tính trên ViewModel", ... chúng là cùng một đối tượng!

+0

Vâng, nó có mùi :) Kịch bản của tôi là như thế này ... Tôi có chức năng cơ bản nhưng trong trường hợp cụ thể này tôi muốn sắp xếp lại một số dữ liệu trên ViewModel của tôi khi một số dữ liệu cơ sở thay đổi. – katit

+0

Tôi vẫn đề xuất sử dụng các phương thức thay vì các sự kiện và sử dụng bố cục trên thừa kế nếu cần: tạo một đối tượng mới chứa cơ sở ViewModel. Nếu không, mọi người sẽ vẫn có quyền truy cập vào chức năng 'cơ sở' của cơ sở ViewModel, mà thực sự bạn dường như đang sửa đổi, do đó, một lớp dẫn xuất không phù hợp với –

+0

Có lẽ phương thức là một cách để đi. Một ví dụ khác. Lớp cơ sở duy trì "trạng thái" của mục nhập dữ liệu của tôi hình thức. Giống như MỚI, CHỈNH SỬA, THÊM. Gói giao diện người dùng liên kết với trạng thái này. Trong máy ảo của tôi, tôi cũng muốn biết về sự thay đổi trạng thái này. Tôi có thể tạo phương thức OnStateChange hoặc tôi có thể đăng ký PropertyChanged. Bạn có thấy cần phải sắp xếp lại hoặc chỉ cần tạo phương pháp? Các phương thức có thể "sạch hơn" để xem xét – katit

2

Cách trực tiếp để đăng ký thay đổi tài sản đang sử dụng INotifyPropertyChanged nếu BaseViewModel bạn thực hiện nó:

PropertyChanged += (obj, args) => 
    { System.Console.WriteLine("Property " + args.PropertyName + " changed"); } 

Nếu không, sau đó nó có phải là một DependencyObject, và tài sản của bạn phải là DependencyProperties (có lẽ là một cách phức tạp hơn).

This article mô tả cách đăng ký DependencyProperty thay đổi.

44

Thông thường tôi sử dụng đăng ký với sự kiện PropertyChanged trong Constructor lớp

public MyViewModel() 
{ 
    this.PropertyChanged += MyViewModel_PropertyChanged; 
} 

và xử lý sự kiện PropertyChanged của tôi trông như thế này:

void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    switch (e.PropertyName) 
    { 
     case "SomeProperty": 
      // Do something 
      break; 
    } 
} 
+0

Có cách nào để loại bỏ "chuỗi ma thuật" trong khi xử lý. (Tôi không sử dụng C# 6) – Marshal

+0

@ Marshal Tôi không chắc chắn, về [bài đăng trên blog này của Josh Smith] (https://joshsmithonwpf.wordpress.com/2009/07/11/one-way-to- tránh lộn xộn-bất động sản-sự kiện-xử lý /)? – Rachel

+0

Tôi nghĩ đó là một giải pháp tốt và đủ khả thi. Cảm ơn bạn đã chỉ đến bài viết. – Marshal