У меня есть элемент управления, который наследует (вы уже догадались).
Я хочу получать уведомление при изменении свойств FontSize
или Style
. В WPF я сделал бы это, позвонив DependencyProperty.OverrideMetadata()
. Конечно, таких полезных вещей в Silverlight нет. Итак, как можно получить такие уведомления?
Silverlight: как получать уведомление об изменении унаследованного DependencyProperty
Ответ 1
Я думаю, что здесь лучший способ. Все еще нужно видеть плюсы и минусы.
/// 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);
}
И теперь вы можете вызвать RegisterForNotification для регистрации для уведомления об изменении свойства элемента, например.
RegisterForNotification("Text", this.txtMain,(d,e)=>MessageBox.Show("Text changed"));
RegisterForNotification("Value", this.sliderMain, (d, e) => MessageBox.Show("Value changed"));
Смотрите мой пост здесь, на том же http://amazedsaint.blogspot.com/2009/12/silverlight-listening-to-dependency.html
Использование бета-версии Silverlight 4.0.
Ответ 2
Это довольно отвратительный взлом, но вы можете использовать двухстороннюю привязку для имитации этого.
то есть. есть что-то вроде:
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);
}
}
затем создайте привязку, например:
<Canvas>
<Canvas.Resources>
<FontSizeListener x:Key="listener" />
</Canvas.Resources>
<MyControlSubclass FontSize="{Binding Mode=TwoWay, Source={StaticResource listener}, Path=FontSize}" />
</Canvas>
затем подключитесь к событию слушателя в вашем подклассе управления.
Ответ 3
Вы не можете внешне прослушивать измененные свойства зависимостей.
Вы можете получить доступ к метаданным Property Dependency Property со следующей строкой кода:
PropertyMetadata metaData = Control.ActualHeightProperty.GetMetadata(typeof(Control));
Тем не менее, единственным открытым участником, который выставлен, является "DefaultValue".
В WPF существует множество способов сделать это. Но в настоящее время они не поддерживаются Silverlight 2 или 3.
Ответ 4
Единственное решение, которое я вижу, - это прослушать событие LayoutUpdated - да, я знаю, что это называется много. Обратите внимание, однако, что в некоторых случаях он не будет вызываться, даже если FontSize или Style изменились.
Ответ 5
Это то, что я всегда использую (не тестировал его на SL, но только в 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 not get
// too Ruby-like
var dpd = DependencyPropertyDescriptor.FromProperty(property, owner.GetType());
dpd.AddValueChanged(owner, handler);
}