Silverlight4 如何实现DataContextChanged事件
2016-03-01 22:01
495 查看
Silverlight4 如何实现DataContextChanged事件,自定义事件参考:/article/6214302.html在WPF中,任何control的Data Context变化的时候,都会显示的抛出一个事件,但是在Silverlight 4 中,却没有类似的功能。为了满足需要,我们可以自己来实现。
View Code
Is your email address OK? You are signed up for our newsletters but youremail address is either unconfirmed, or has not been reconfirmed in a long time. Please clickhere to have a confirmation email sent so we can confirm your email address and start sending you newsletters again. Alternatively, you canupdate your subscriptions.One known issue with Silverlight is that the
public interface IDataContextChangedHandler<T> where T : FrameworkElement { void OnDataContextChanged(T sender, DependencyPropertyChangedEventArgs e); } public static class DataContextChangedHelper<T> where T : FrameworkElement, IDataContextChangedHandler<T> { public static readonly DependencyProperty InternalDataContextProperty = DependencyProperty.Register("InternalDataContext", typeof(Object), typeof(T), new PropertyMetadata(OnDataContextChanged)); public static void Bind(T control) { control.SetBinding(InternalDataContextProperty, new Binding()); } private static void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { T control = (T)sender; control.OnDataContextChanged(control, e); } }如何使用:在自定义control的构造函数中设置binding即可。参考的文档没有说清楚如何使用,我是看下边的英文原版,才有的灵感,差点放弃了 by dacong
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SilverlightContol1 :UserControl,IDataContextChangedHandler<SilverlightContol1> { public Gauge() { InitializeComponent(); DataContextChangedHelper<SilverlightContol1>.Bind(this); }
public void DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { MessageBox.Show("DataContext Changed event");
} }还有个英文版的参考http://www.codeproject.com/Articles/38559/Silverlight-DataContext-Changed-Event?fid=1544514&df=90&mpp=25&noise=3&prof=True&sort=Position&view=Quick&spc=RelaxedOne known issue with Silverlight is that the DataContext bound to a control may change, but there is no readily available change event. Unlike WPF, you don't have an explicit event to register with in order to trackchanges.
![](http://www.codeproject.com/images/warning48.png)
DataContextbound to a control may change, but there is no readily available change event. Unlike WPF, you don't have an explicit event to register with in order to track changes. This becomes a problemin controls like the
DataGridcontrol which reuses the same control instances for each page. Even though fresh data is bound, if your control isn't aware that the data context changed, it will keep stale content.If you search online you'll find the solution is simple: you create a dependency property that is actually based on the data context (call it a "dummy" property) and then register for changes to that property. I was glad to find the solution but wanted somethinga little more reusable (remember, I like the DRY principle: don't repeat yourself, so when I find myself writing the same line of code more than once I have to go back and refactor).The solution? I was able to find something that I think works well and involves an interface and a static class.First, I want to identify when a control should be aware of changes to
DataContextand also provide a method to call when this happens. That was easy enough. I created
IDataContextChangedHandlerand defined it like this:Hide Copy Code
public interface IDataContextChangedHandler<T> where T: FrameworkElement{void DataContextChanged(T sender, DependencyPropertyChangedEventArgs e);}As you can see, it is a simple interface. A method is called with the sender (which will presumably be the control itself) and the arguments for a dependency property changed event. It is typed to T, of course.Next, I used generics to create a base class that manages the "fake" dependency property:Hide Copy Code
public static class DataContextChangedHelper<T> where T: FrameworkElement, IDataContextChangedHandler<T>{private const string INTERNAL_CONTEXT = "InternalDataContext";public static readonly DependencyProperty InternalDataContextProperty =DependencyProperty.Register(INTERNAL_CONTEXT,typeof(Object),typeof(T),new PropertyMetadata(_DataContextChanged));private static void _DataContextChanged(object sender, DependencyPropertyChangedEventArgs e){T control = (T)sender;control.DataContextChanged(control, e);}public static void Bind(T control){control.SetBinding(InternalDataContextProperty, new Binding());}}As you can see, the class does a few things and works for any framework element, which is a "basic building block" that supports binding. It is typed to the
FrameworkElementbut also requires that the target implements
IDataContextChangedHandler. It creates a dependency property. Because the data context can be any object, the type of the dependency is
object, but the type of the parent is the framework element itself ("T"). When something happens to the property, it will invoke
_DataContextChanged.The event handler is sent the control that raised the event as well as the arguments for the old and new properties in the data context. We simply cast the sender back to its original type of T. Then, because we know it implements
IDataContextChangedHandler, we can simply call
DataContextChanged.Finally, there is a static call to bind the control itself.Now let's put the pieces together. Let's say you have a control that makes a gauge based on a data value, and you want to put the control in the grid. You need to know when the
DataContextchanges, because you will update your gauge. The control will look like this:Hide Copy Code
public partial class Gauge : IDataContextChangedHandler<Gauge>{public Gauge(){InitializeComponent();DataContextChangedHelper<Gauge>.Bind(this);}public void DataContextChanged(Gauge sender, DependencyPropertyChangedEventArgs e){if (e.NewValue != null){int gaugeLevel = (int)e.NewLevel;_UpdateImage(gaugeLevel);}}}And there you have it - to register for the data context changing, we simply implemented
IDataContextChangedHandlerand then registered by calling
Bindin our constructor.需要补充的是, 这个功能在Silverlight 5中已经自带。
相关文章推荐
- iOS实践03
- 【NOI2001】食物链
- 矩形嵌套(LIS)
- C++智能指针简单剖析
- 集合无序性的体验
- Android中SheardPreference的使用
- ubuntu 快捷键
- 数据结构与算法分析 学习笔记——最大子序列求和问题
- PAT-A1011 World Cup Betting (20)(模拟)
- 值类型,引用类型
- myecplise 中文乱码
- 升级wamp5集成安装包 php5.2到php5.3
- spring单元测试
- java的collection类使用
- git比较远程和本地
- nodejs String
- Raft 为什么是更易理解的分布式一致性算法
- Raft 为什么是更易理解的分布式一致性算法
- Vi(Vim)快捷键
- 寻宝