I have bad news for you.
Inside DependencyObject.SetValue
the check is located, which verify if new value equals to old value. So if you are binded to A.B
, and changing of A.B.C
produces PropertyChanged event for A.B
, Binding
mechanizm will handle this event and even call DependencyObject.SetValue
. But then (due to equality of old and new A.B
values) no changes will be applied to DP.
In order to achieve correct DP fireing, you should create new instance of A.B, that concludes in great headache.
UPDATED
You could use Freezable object, which supports notification that it has changed when its property is changed. DependencyObject works with Freezables correctly, so next example does what you need.
Model classes:
public class A
{
public A()
{
this.B = new B();
}
public B B
{
get; private set;
}
}
public class B : Freezable, INotifyPropertyChanged
{
protected override Freezable CreateInstanceCore()
{
return new B();
}
private string _c = "initial string";
public string C
{
get
{
return _c;
}
set
{
this._c = value;
this.OnPropertyChanged("C");
this.OnChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var safe = this.PropertyChanged;
if (safe != null)
{
safe(this, new PropertyChangedEventArgs(name));
}
}
}
Xaml:
<StackPanel>
<TextBox Text="{Binding A.B.C}" />
<TextBox Text="{Binding MyProperty.C}" />
<Button Click="Button_Click"/>
</StackPanel>
Code behind:
public partial class TextBoxesView : UserControl
{
public TextBoxesView()
{
InitializeComponent();
this.A = new A();
this.DataContext = this;
BindingOperations.SetBinding(this, TextBoxesView.MyPropertyProperty, new Binding("A.B"));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.A.B.C = DateTime.Now.ToString();
}
public A A
{
get;
private set;
}
public B MyProperty
{
get
{
return (B)this.GetValue(TextBoxesView.MyPropertyProperty);
}
set
{
this.SetValue(TextBoxesView.MyPropertyProperty, value);
}
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty",
typeof(B),
typeof(TextBoxesView),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, (d, e) => { }));
}
Mode=TwoWay
to the binding. However, I'm not sure I understood correctly your question, could you add some code? – Damascus