Silverlight: How to receive notification of a change in an inherited DependencyProperty

11,965

Solution 1

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.

Solution 2

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.

Share:
11,965
MojoFilter
Author by

MojoFilter

Updated on June 05, 2022

Comments

  • MojoFilter
    MojoFilter about 2 years

    I have a control which inherits from (you guessed it) Control. I want to receive a notification whenever the FontSize or Style properties are changed. In WPF, I would do that by calling DependencyProperty.OverrideMetadata(). Of course, useful things like that have no place in Silverlight. So, how might one receive those kinds of notifications?

  • MojoFilter
    MojoFilter about 15 years
    I'm pretty sure DependencyPropertyDescrtiptors are mythical beasts in Silverlight, unfortunately.
  • markti
    markti about 15 years
    DependencyPropertyDescriptor is not supported by Silverlight 2 or 3
  • MojoFilter
    MojoFilter over 14 years
    I like that this is a nicer way of wrapping up that ugly binding, but that is an awfully heavy way to get property change notifications.
  • amazedsaint
    amazedsaint over 14 years
    As long as we need to do it entirely from the code, I guess we don't have another option till we get the DependencyPropertyDescriptor in Silverlight from MS
  • Ian Oakes
    Ian Oakes over 13 years
    I've also used this approach, unfortunately it leaks memory. In my experience it will hold a reference to what ever element you use it with, which will in turn hold on to other objects. The culprit appears to be the callback which will retain a reference to your view for the life of your application.
  • Amir Karimi
    Amir Karimi almost 13 years
    When the MyControlSubclass FontSize property change, the binding will be clear so it seems it doesn't work? not?
  • Dr. Andrew Burnett-Thompson
    Dr. Andrew Burnett-Thompson over 12 years
    It works (+1!) but as Ian said its not optimal. As a workaround I've moved the attached property (in my case called ListenAttachedIsEnabledProperty to the class I want to override and added the following two lines in the constructor var b = new Binding("IsEnabled") { Source = this }; SetBinding(ListenAttachedIsEnabledProperty, b);
  • Firo
    Firo about 11 years
    it will throw when calling RegisterForNotification for multiple textboxes probably because you can't create multiple DependencyProperties with the same Name.