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

你离开我真会死。 提交于 2019-12-18 10:45:25

问题


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?


回答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.




回答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.




回答3:


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.




回答4:


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.




回答5:


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


来源:https://stackoverflow.com/questions/834929/silverlight-how-to-receive-notification-of-a-change-in-an-inherited-dependencyp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!