我有一个控件,它继承自(你猜对了)Control。
我想在FontSize
或Style
属性发生更改时收到通知。在WPF中,我会通过调用DependencyProperty.OverrideMetadata()
来做到这一点。当然,有用的东西在Silverlight中没有位置。那么,如何收到这类通知呢?
答案 0 :(得分:16)
我认为这是一种更好的方法。仍然需要看到利弊。
/// 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 beta。
答案 1 :(得分:6)
这是一个相当恶心的黑客,但你可以使用双向绑定来模拟这个。
即。有类似的东西:
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>
然后连接到控件子类中的侦听器事件。
答案 2 :(得分:0)
您无法从外部侦听依赖属性更改通知。
您可以使用以下代码行访问依赖项属性元数据:
PropertyMetadata metaData = Control.ActualHeightProperty.GetMetadata(typeof(Control));
但是,唯一公开的成员是“DefaultValue”。
在WPF中有很多种方法可以做到这一点。但目前Silverlight 2或3不支持它们。
答案 3 :(得分:0)
我看到的唯一解决方案是收听LayoutUpdated事件 - 是的,我知道它被调用很多。但请注意,在某些情况下,即使FontSize或Style已更改,也不会调用它。
答案 4 :(得分:-2)
这是我一直使用的(虽然在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);
}