WPF – Tự động hiện thực INotifyPropertyChanged với DynamicObject

dynamicĐây là kĩ thuật sử dụng dynamic trong .Net để tạo các đối tượng đại diện (proxy) cho đối tượng thực sự bạn cần hiện thực INotifyPropertyChange. Ý tưởng của phương pháp này là lợi dụng khả năng của đối tượng DynamicObject cho phép ta xử lý thủ công các thao tác truy xuất đến property để kích hoạt event của INotifyPropertyChanged.

Bài viết này dựa trên bài: WPF – Easy INotifyPropertyChanged Via DynamicObject Proxy của Dean Chalk. Bạn cũng có thể tìm hiểu thêm về nền tảng DLR và lập trình dynamic tại:
DLR – Dynamic Programming: ExpandoObject, DynamicObject và Dynamic Method Bags
Sourcecode của class:

public class AutoNotifyProxy<T> : DynamicObject, INotifyPropertyChanged
{
    private readonly T _instance;
    private readonly Type _type;

    public AutoNotifyProxy(T instance)
    {
        _instance = instance;
        _type = typeof(T);
    }
    // set property
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        PropertyInfo prop = _type.GetProperty(binder.Name);
        if (prop != null)
        {
            var oldValue = prop.GetValue(_instance, null);
            if (!oldValue.Equals(value))
            {
                prop.SetValue(_instance, value, null);
                OnPropertyChanged(binder.Name);
                return true;
            }
        }
        return false;
    }
    // get property
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        PropertyInfo prop = _type.GetProperty(binder.Name);
        if (prop != null)
        {
            result = prop.GetValue(_instance, null);
            return true;
        }
        result = null;
        return false;
    }
    #region INotifyPropertyChanged Members

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

Khi sử dụng bạn phải dùng từ khóa dynamic để khai báo:

var st= new Student() { Birthday = DateTime.Now, FullName="A"};

dynamic obj=new AutoNotifyProxy&lt;Student&gt;(st);

Đối tượng obj bây giờ có thể được binding và sẽ giao diện sẽ tự động cập nhật mỗi khi dữ liệu của nó bị thay đổi.

https://yinyangit.wordpress.com

Bài liên quan

Advertisements

11 thoughts on “WPF – Tự động hiện thực INotifyPropertyChanged với DynamicObject

  1. Bạn có thể đọc bài viết MVVM trong WPF (Part 1/4): INotifyPropertyChanged và INotifyCollectionChanged để hiểu được công dụng của INotifyPropertyChanged.

    Mục đích của việc sử dụng dynamic trong bài này là cung cấp cho đối tượng khả năng tự động kích hoạt một event (cụ thể là PropertyChanged) mỗi khi giá trị của một property bị thay đổi.

    Phản hồi
  2. Pingback: MVVM trong WPF (Part 1/4): INotifyPropertyChanged và INotifyCollectionChanged « Nguyễn Ngọc Vạn's Blog

  3. Cho mình hỏi chút về lớp AutoNotifyProxy.
    ở ví dụ trên bạn chỉ gán 1 đối tượng đơn
    var st= new Student() { Birthday = DateTime.Now, FullName=”A”};
    – Giả sử mình muốn gán 1 đối tượng dạng Collection thì làm như thế nào ?
    Giả sử mình truy vấn CSDL,Với câu truy vấn : DataContext db = new DataContext; var st = db.Students ;
    – Khi này câu truy vấn trả về kiểu Linq,làm sao để gán vào lớp AutoNotifyProxy để binding được
    Cảm ơn bạn rất nhiều .
    rất mong bạn sớm trả lời,vì thực sự mấy hôm nay mình đang bế tắc vụ này và cái vụ EF code first

    Phản hồi
    • LINQ chỉ là một cú pháp, ko phải là kiểu dữ liệu. Vì vậy bạn vẫn có thể sử dụng như những đối tượng thông thường khác. AutoNotifyProxy này chỉ có mục đích cho các đối tượng thành phần, không phải cho collection. Một collection phải là dạng ObservableCollection. Khi đó mỗi khi các thành phần của nó notify thì collection cũng sẽ nhận biết được và cũng kích hoạt notify tương ứng.

      Phản hồi
  4. Uhm,mình xin lỗi khi hỏi chưa rõ.Ý mình hỏi là câu truy vấn dùng linq của mình ( hình như trả về IEnum gì đó ) .Sau đó gán lên View.
    Sau khi thực hiện các thêm,sửa,xóa mình muốn nó cũng thực hiện thay đổi luôn trên View.Khi ấy ở ViewModel mình không biết làm thế nào.
    Vấn đề tiếp là các class mình tạo từ Linq to sql,EF thì lại mất công cài đặt thủ công gọi event OnPropertyChanged cho mỗi thuộc tính thì bất tiện quá.Không biết bạn có cách nào hay hơn.Đọc đến bài tự động hiện thực INotifyPropertyChanged với dynamic mình cứ nghĩ là có cách đơn giản.Thì ra vẫn chưa ổn ah .
    Bắt đầu thấy nản nản cái món MVVM lắm rồi

    Phản hồi
  5. a cho e hỏi. e có làm 1 ứng dụng silverlight. nhưng sau 1 thời gian chạy thì nó chiếm dụng ram khá nhiều làm ảnh hưởng tới tốc độ chạy của chương trình. A có cách nào làm cho nó k chiếm dụng ram quá nhiều hoặc giảm bớt được k a. Vấn đề này khá là gấp nên nếu a nhận được thì rep sớm giúp e nha. E cám ơn a rất nhiều

    Phản hồi
  6. Pingback: MVVM 1 INotifyPropertyChanged và INotifyCollectionChanged – Blog Dương Xuân Trà

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s