I have a control which inherits from (you guessed it) Control.
I want to receive a notification whenever the FontSize
or Style
properties are chang
This is what I always use (haven't tested it on SL though, just on WPF):
/// <summary>
/// This method registers a callback on a dependency object to be called
/// when the value of the DP changes.
/// </summary>
/// <param name="owner">The owning object.</param>
/// <param name="property">The DependencyProperty to watch.</param>
/// <param name="handler">The action to call out when the DP changes.</param>
public static void RegisterDepPropCallback(object owner, DependencyProperty property, EventHandler handler)
{
// FIXME: We could implement this as an extension, but let's not get
// too Ruby-like
var dpd = DependencyPropertyDescriptor.FromProperty(property, owner.GetType());
dpd.AddValueChanged(owner, handler);
}
It's a rather disgusting hack, but you could use a two-way binding to simulate this.
i.e. have something like:
public class FontSizeListener {
public double FontSize {
get { return fontSize; }
set { fontSize = value; OnFontSizeChanged (this, EventArgs.Empty); }
}
public event EventHandler FontSizeChanged;
void OnFontSizeChanged (object sender, EventArgs e) {
if (FontSizeChanged != null) FontSizeChanged (sender, e);
}
}
then create the binding like:
<Canvas>
<Canvas.Resources>
<FontSizeListener x:Key="listener" />
</Canvas.Resources>
<MyControlSubclass FontSize="{Binding Mode=TwoWay, Source={StaticResource listener}, Path=FontSize}" />
</Canvas>
then hook up to the listener's event in your control subclass.
You cannot externally listen to dependency property changed notifications.
You can access the Dependency Property Metadata with the following line of code:
PropertyMetadata metaData = Control.ActualHeightProperty.GetMetadata(typeof(Control));
However, the only public member that is exposed is "DefaultValue".
There are a multitude of ways to do this in WPF. But they are currently not supported by Silverlight 2 or 3.
I think here is a better way. Still need to see the pros and Cons.
/// Listen for change of the dependency property
public void RegisterForNotification(string propertyName, FrameworkElement element, PropertyChangedCallback callback)
{
//Bind to a depedency property
Binding b = new Binding(propertyName) { Source = element };
var prop = System.Windows.DependencyProperty.RegisterAttached(
"ListenAttached"+propertyName,
typeof(object),
typeof(UserControl),
new System.Windows.PropertyMetadata(callback));
element.SetBinding(prop, b);
}
And now, you can call RegisterForNotification to register for a change notification of a property of an element, like .
RegisterForNotification("Text", this.txtMain,(d,e)=>MessageBox.Show("Text changed"));
RegisterForNotification("Value", this.sliderMain, (d, e) => MessageBox.Show("Value changed"));
See my post here on the same http://amazedsaint.blogspot.com/2009/12/silverlight-listening-to-dependency.html
Using Silverlight 4.0 beta.
The only solution I see is to listen to the LayoutUpdated event - yes, I know it is called a lot. Note however that in some cases it won't be called even though FontSize or Style has changed.