Silverlight: come ricevere la notifica di una modifica in una DependencyProperty ereditata
-
08-07-2019 - |
Domanda
Ho un controllo che eredita dal controllo (hai indovinato).
Desidero ricevere una notifica ogni volta che le proprietà FontSize
o Style
vengono modificate. In WPF, lo farei chiamando DependencyProperty.OverrideMetadata ()
. Certo, cose utili come quelle non hanno posto in Silverlight. Quindi, come si potrebbe ricevere quel tipo di notifiche?
Soluzione
Penso che qui sia un modo migliore. Devo ancora vedere i pro e i contro.
/// 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);
}
E ora puoi chiamare RegisterForNotification per registrarti per una notifica di modifica di una proprietà di un elemento, come.
RegisterForNotification("Text", this.txtMain,(d,e)=>MessageBox.Show("Text changed"));
RegisterForNotification("Value", this.sliderMain, (d, e) => MessageBox.Show("Value changed"));
Vedi il mio post qui sullo stesso http: // amazedsaint.blogspot.com/2009/12/silverlight-listening-to-dependency.html
Utilizzo di Silverlight 4.0 beta.
Altri suggerimenti
È un trucco piuttosto disgustoso, ma potresti usare un'associazione bidirezionale per simularlo.
vale a dire. avere qualcosa del tipo:
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);
}
}
quindi crea l'associazione come:
<Canvas>
<Canvas.Resources>
<FontSizeListener x:Key="listener" />
</Canvas.Resources>
<MyControlSubclass FontSize="{Binding Mode=TwoWay, Source={StaticResource listener}, Path=FontSize}" />
</Canvas>
quindi aggancia l'evento dell'ascoltatore nella tua sottoclasse di controllo.
Non è possibile ascoltare esternamente le notifiche di modifica della proprietà di dipendenza.
È possibile accedere ai metadati della proprietà di dipendenza con la seguente riga di codice:
PropertyMetadata metaData = Control.ActualHeightProperty.GetMetadata(typeof(Control));
Tuttavia, l'unico membro pubblico esposto è " DefaultValue " ;.
Ci sono molti modi per farlo in WPF. Ma al momento non sono supportati da Silverlight 2 o 3.
L'unica soluzione che vedo è ascoltare l'evento LayoutUpdated - sì, lo so che si chiama molto. Si noti tuttavia che in alcuni casi non verrà chiamato anche se FontSize o Style sono cambiati.
Questo è quello che uso sempre (non l'ho ancora testato su SL, solo su 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);
}