My question concerns Silverlight (but I guess WPF as well).
Basically I know, how to create dependency property in a user control and how to make it work. But what i was trying to do, and didn’t succeded is: to create dependency property (or more than one) in a class, and this class will become a dependency property for my user control.
With other words:
// my UserControl
public class DPTest : UserControl
{
// dependency property, which type is a class, and this class will be holding other dependency properties
public static readonly DependencyProperty GroupProperty =
DependencyProperty.Register("Group", typeof(DPGroup), typeof(DPTest), new PropertyMetadata(new DPGroup(), OnPropertyChanged));
public DPGroup Group
{
get { return (DPGroup)GetValue(GroupProperty); }
set { SetValue(GroupProperty, value); }
}
// this occurs only when property Group will change, but not when a member of property Group will change
static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DPTest g = d as DPTest;
// etc.
}
}
// a class, where I want to hold my dependency properties
public class DPGroup : DependencyObject
{
public static readonly DependencyProperty MyProperty1Property =
DependencyProperty.RegisterAttached("MyProperty1", typeof(int), typeof(DPGroup), new PropertyMetadata(1, OnPropertyChanged));
public int MyProperty1
{
get { return (int)GetValue(MyProperty1Property); }
set { SetValue(MyProperty1Property, value); }
}
// I would like to notify "the parent" (which means user control "DPTest" ), that member MyProperty1 has changed
static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DPTest g = d as DPTest;
if (g != null) g.textBox1.Text = g.Group.MyProperty1.ToString();
}
}
What I want to achieve is to notify (in design time in XAML) a user control DPTest, that member of Group property (Group.MyProperty1) changed it’s value. I managed to make it happen in a run-time, for example by using event handler defined in DPGroup class, but this doesn’t work in design-time in xaml.
<Grid x:Name="LayoutRoot" Background="White">
<local:DPTest>
<local:DPTest.Group>
<local:DPGroup MyProperty1="2"/>
</local:DPTest.Group>
</local:DPTest>
</Grid>
It works, but only first time, during creating tag:
<local:DPGroup MyProperty1="2"/>
and after this, changing value of MyProperty1, does not fire DPTest.OnPropertyChange. Probably fires DBGroup.OnPropertyChanged, but this of course does not notify user control DPTest about it. So how to make DPTest know, that the Group.MyProperty1 has changed?
I don’t want to make any bindings from MyProperty1 to respective property created inside user control DPTest (not to duplicate properties), the point is to have a group of properties in separate class, so i can use this group more than once, like:
// my UserControl
public class DPTest : UserControl
{
public DPGroup Group1 { ... }
public DPGroup Group2 { ... }
}
I see some analogy to UIElement.RenderTransform (let’s say it is my Group property) which holds for example ScaleTransform
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RenderTransform>
<ScaleTransform ScaleX="0.4"/>
</Grid.RenderTransform>
</Grid>
ScaleX is an analogy to MyProperty1. The difference is, that changing value of ScaleX (in XAML) will reflect immediate changes in design-time, and exactly this I am trying to achieve.
I was trying to find a solution in entire google/stack overflow and others, but none found. Everywhere are just examples of creating dependency properties inside a user control.
Thank you for your time.
Any help much appreciated.
edit: based on Harlow Burgess answer, a managed to make a working example in Silverlight. I put the whole solution below as an separate answer.
From: http://msdn.microsoft.com/en-us/library/ms752914.aspx#setting_properties_data_binding
It would be inefficient to design a system that notifies an entire object graph anytime any property of any subproperty (of any subproperty, of any subproperty, …) changes. So instead you should use Data Binding to specific properties when you need to do something when that property changes, or if you really want to be notified when any subproperty changes, you should implement INotifyPropertyChanged.
How to: Implement Property Change Notification
Example: