2011-09-27 42 views
7

我想將窗口中的TextBox綁定到作爲視圖模型的變量的類中包含的屬性,並確保INotifyPropertyChanged的PropertyChanged事件從該類傳播到父級。INotifyPropertyChanged在子類

讓我用一個例子:

(Window的DataContext設置視圖模型的實例)

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"); 
     } 
    } 
    ... 
} 

本例中的問題是,當屬性的變化,綁定的文本框不會更新綁定,因爲我認爲它正在監聽ViewModel的PropertyChanged事件,而不是其他類的實例。

關於如何彌補這種情況的任何想法?我正在考慮將OtherClass的INotifyPropertyChanged鏈接到它的父類,但是必須有更好的方法。

回答

6

爲什麼不直接綁定到類屬性而不是使用代理?

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

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

然後在你結合你可以簡單地通過子類

{Binding MyOtherClass.Attribute} 

一滴死簡單的例子引用屬性,但它的工程!

後面代碼:

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 
} 

的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

下降死簡單的例子是最好的例子:) – Moulde

+0

這是不實際的,如果SomeSubClass包含一堆屬性。你真的要複製所有這些屬性嗎? – Sean

+0

@Sean - 我不確定你的意思是「重複所有這些屬性」。在這個例子中,只是巧合,名字是在父母和孩子身上定義的。這對潛在的問題沒有任何影響。主要的是,你可以直接綁定到子類的屬性,而不是嘗試使用代理變量。從這個意義上說,將會有零重複。 – Josh

0

我覺得父類應該訂閱孩子propertyCahnged event..something像:

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

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

NotifyChildAttributeChanged基本上只有聽的「屬性」屬性,並觸發的通知的PropertyChanged方法它自己..

當然,我們的父類必須實現INotifyPropertyChanged以及所有ViewModels(最好)和您的DataContext將檢測到更改。

4

你需要做這樣的事情:

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

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

我這裏不表現出來,但你也應該實現IDisposable並從你的孩子PropertyChanged事件退訂,否則將導致內存泄漏。

或者,您可以將classInstance作爲公共屬性公開,並將綁定設置爲:ViewModel.classInstance。請注意,這需要屬性而不是字段本身。

+0

這對我的作品改變NotifyPropertyChangedEventArgs爲PropertyChangedEventArgs。 –