2009-05-07 3 views
12

J'ai un contrôle qui hérite de (vous l'avez deviné) Contrôle. Je souhaite recevoir une notification chaque fois que les propriétés FontSize ou Style sont modifiées. Dans WPF, je le ferais en appelant le DependencyProperty.OverrideMetadata(). Bien sûr, des choses utiles comme ça n'ont pas leur place dans Silverlight. Alors, comment pourrait-on recevoir ce genre de notifications?Silverlight: Comment recevoir une notification d'un changement dans un DependencyProperty hérité

Répondre

15

Je pense que c'est un meilleur moyen. Encore besoin de voir les avantages et les inconvénients.

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

Et maintenant, vous pouvez appeler RegisterForNotification pour vous inscrire à une notification de changement d'une propriété d'un élément, comme.

RegisterForNotification("Text", this.txtMain,(d,e)=>MessageBox.Show("Text changed")); 
RegisterForNotification("Value", this.sliderMain, (d, e) => MessageBox.Show("Value changed")); 

Voir mon post ici sur le même http://amazedsaint.blogspot.com/2009/12/silverlight-listening-to-dependency.html

En utilisant Silverlight 4.0 beta.

+0

J'aime que c'est une façon plus agréable d'envelopper cette liaison laide, mais c'est un moyen terriblement lourd d'obtenir des notifications de changement de propriété. – MojoFilter

+1

Tant que nous devons le faire entièrement à partir du code, je suppose que nous n'avons pas une autre option jusqu'à ce que nous obtenions le DependencyPropertyDescriptor dans Silverlight de MS – amazedsaint

+0

J'ai également utilisé cette approche, malheureusement, il fuit la mémoire. Dans mon expérience, il contiendra une référence à n'importe quel élément avec lequel vous l'utilisez, qui à son tour s'accrocheront à d'autres objets.Le coupable semble être le rappel qui conservera une référence à votre vue pour la vie de votre application. –

-2

C'est ce que j'utilise toujours (ont pas testé sur SL si, juste 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); 
    } 
+5

Je suis assez sûr que DependencyPropertyDescrtiptors sont des bêtes mythiques dans Silverlight, malheureusement. – MojoFilter

+2

DependencyPropertyDescriptor n'est pas pris en charge par Silverlight 2 ou 3 – markti

0

Vous ne pouvez pas écouter de l'extérieur à la dépendance des biens changé les notifications.

Vous pouvez accéder aux métadonnées de la propriété de dépendance avec la ligne de code suivante:

PropertyMetadata metaData = Control.ActualHeightProperty.GetMetadata(typeof(Control)); 

Cependant, le seul membre du public qui est exposé est « DefaultValue ».

Il existe une multitude de méthodes pour cela dans WPF. Mais ils ne sont actuellement pas pris en charge par Silverlight 2 ou 3.

0

La seule solution que je vois est d'écouter l'événement LayoutUpdated - oui, je sais que ça s'appelle beaucoup. Notez cependant que dans certains cas, il ne sera pas appelé même si FontSize ou Style a changé.

6

C'est un hack plutôt répugnant, mais vous pouvez utiliser une liaison bidirectionnelle pour simuler cela.

dire quelque chose comme:

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

puis créer la liaison comme:

<Canvas> 
    <Canvas.Resources> 
    <FontSizeListener x:Key="listener" /> 
    </Canvas.Resources> 

    <MyControlSubclass FontSize="{Binding Mode=TwoWay, Source={StaticResource listener}, Path=FontSize}" /> 
</Canvas> 

puis accrocher à l'événement de l'auditeur dans votre sous-classe de contrôle.

+0

Lorsque la propriété MyControlSubclass FontSize est modifiée, la liaison est désactivée et semble donc ne pas fonctionner. ne pas? –

Questions connexes