2011-09-27 28 views
7

Tôi muốn liên kết một TextBox trong cửa sổ với thuộc tính chứa trong một lớp là biến của viewmodel và đảm bảo rằng sự kiện PropertyChanged của INotifyPropertyChanged được truyền từ lớp này sang cha mẹ.INotifyPropertyChanged trong phân lớp

Hãy để tôi minh họa bằng một ví dụ:

(DataContext Window được thiết lập để một thể hiện của ViewModel)

public class ViewModel { 
    private OtherClass classInstance = new OtherClass(); 

    public int Attribute { 
     get { return classInstance.Attribute; } 
    } 
} 

public class OtherClass : INotifyPropertyChanged { 
    private int _attribute; 
    public int Attribute { 
     get { return _attribute; } 
     set { 
      _attribute = value; 
      PropertyChanged("Attribute"); 
     } 
    } 
    ... 
} 

Vấn đề trong ví dụ này là, khi thay đổi thuộc tính, các Textbox bị ràng buộc không cập nhật các ràng buộc kể từ khi tôi giả sử nó nghe sự kiện PropertyChanged của ViewModel và không phải là trường hợp của OtherClass.

Bất kỳ ý tưởng nào về cách khắc phục tình huống này? Tôi đã suy nghĩ về chaining của OtherClass's INotifyPropertyChanged để của cha mẹ của nó, nhưng có phải là một cách tốt hơn.

Trả lời

6

Tại sao không liên kết trực tiếp với thuộc tính lớp thay vì sử dụng proxy?

public class ViewModel { 
    private OtherClass classInstance = new OtherClass(); 

    public OtherClass MyOtherClass { 
     get { return classInstance; } 
    } 
} 

Sau đó, trong ràng buộc bạn chỉ có thể tham khảo bất động sản thông qua các lớp con

{Binding MyOtherClass.Attribute} 

Sự sụt giảm chết ví dụ đơn giản, nhưng nó hoạt động của bạn!

Bộ luật Đằng sau:

public partial class MainWindow : Window { 
    private readonly SomeClass _someClass = new SomeClass(); 

    public MainWindow() { 
     InitializeComponent(); 
     DataContext = _someClass; 
    } 
} 

public class SomeClass: INotifyPropertyChanged {  
    private readonly SomeSubClass _mySubClass = new SomeSubClass(); 

    public SomeSubClass MySubClass { 
     get { return _mySubClass; } 
    } 

    private String _name; 
    public String Name { 
     get { return _name; } 
     set { 
     _name = value; 
     OnPropertyChanged("Name"); 
     } 
    } 

    //Property Change Stuff 
} 

public class SomeSubClass : INotifyPropertyChanged { 
    private String _name; 
    public String Name { 
     get { 
     return _name; 
     } 
     set { 
     _name = value; 
     OnPropertyChanged("Name"); 
     } 
    } 

    //Property Change Stuff 
} 

Các XAML:

<Window x:Class="JWC.Examples.WPF.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow"> 
    <StackPanel> 
     <Label Content="Name" VerticalAlignment="Top" /> 
     <TextBox Text="{Binding Name}" /> 
     <Label Content="SubClass.Name" /> 
     <TextBox Text="{Binding MySubClass.Name}" /> 
     <Label Content="Bound to Name" /> 
     <TextBlock Text="{Binding Name}" /> 
     <Label Content="Bound to MySubClass.Name" /> 
     <TextBlock Text="{Binding MySubClass.Name}" /> 
    </StackPanel> 
</Window> 
+0

Thả ví dụ đơn giản chết là loại ví dụ tốt nhất :) – Moulde

+0

Điều này không thực tế nếu SomeSubClass chứa một đống thuộc tính. Bạn có thực sự sẽ sao chép tất cả các thuộc tính đó không? – Sean

+0

@Sean - Tôi không chắc chắn ý của bạn là gì "sao chép tất cả các thuộc tính đó". Trong ví dụ đó chỉ là trùng hợp ngẫu nhiên mà Tên được xác định trên phụ huynh và đứa trẻ. Nó làm cho không có sự khác biệt cho câu hỏi cơ bản. Chủ yếu, bạn có thể liên kết trực tiếp với thuộc tính lớp con thay vì cố sử dụng các biến proxy. Theo nghĩa đó, sẽ không có sự trùng lặp. – Josh

0

Tôi nghĩ rằng tầng lớp phụ huynh nên đăng ký cho đứa trẻ propertyCahnged event..something như:

public class ViewModel 
{ 
    private OtherClass classInstance = new OtherClass(); 

    public ViewModel() 
    { 
     classInstance.PropertyChanged += NotifyChildAttributeChanged; 
    } 
    public int Attribute 
    { 
     get { return classInstance.Attribute; } 
    } 
} 

NotifyChildAttributeChanged về cơ bản là một phương pháp mà chỉ nghe đến "Thuộc tính" bất động sản và bắn một thông báo PropertyChanged của riêng của nó ..

Tất nhiên lớp cha mẹ của chúng tôi phải triển khai INotifyPropertyChanged cũng như tất cả ViewModels (tốt hơn) và DataContext của bạn sẽ phát hiện thay đổi.

4

Bạn sẽ cần phải làm một cái gì đó như thế này:

public class ViewModel { 
    public ViewModel() { 
     classInstance = new OtherClass(); 
     classInstance.PropertyChanged += HandleAttributeChanged; 
    } 

    private void HandleAttributeChanged(object Sender, NotifyPropertyChangedEventArgs args) { 
     PropertyChanged("Attribute"); 
    } 
} 

Tôi không thấy nó ở đây, nhưng bạn cũng nên thực hiện IDisposable và huỷ đăng ký từ sự kiện PropertyChanged trên con quý vị, nếu không bạn sẽ bị rò rỉ bộ nhớ.

Hoặc bạn có thể hiển thị classInstance làm tài sản công khai và đặt ràng buộc của bạn thành: ViewModel.classInstance. Lưu ý rằng điều này cần phải là thuộc tính chứ không phải chính trường đó.

+0

Nó làm việc cho tôi thay đổi NotifyPropertyChangedEventArgs cho PropertyChangedEventArgs. –

0

Để làm được việc này bạn cần phải thực hiện INotifyPropertyChanged trên mô hình quan điểm của bạn là tốt.Chỉ cần thêm giao diện và sự kiện và phần còn lại sẽ tự chăm sóc - không cần phải kết nối các sự kiện/cuộc gọi với nhau.

Kiểm tra điều này để sử dụng sự phản chiếu để có được thuộc tính.

http://tsells.wordpress.com/2011/02/08/using-reflection-with-wpf-and-the-inotifypropertychanged-interface/

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