国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Silverlight4 如何實現DataContextChanged事件
                 轉載 2016年03月01日 22:01:02

Silverlight4 如何實現DataContextChanged事件,自定義事件

參考:http://www.cnblogs.com/allanli/archive/2012/04/09/2439008.html

在WPF中,任何control的Data Context變化的時候,都會顯示的拋出一個事件,但是在Silverlight 4 中,卻沒有類似的功能。為了滿足需要,我們可以自己來實現。

  1. public interface IDataContextChangedHandler<T> where T : FrameworkElement  
  2.     {  
  3.         void OnDataContextChanged(T sender, DependencyPropertyChangedEventArgs e);  
  4.     }  
  5.   
  6.     public static class DataContextChangedHelper<T> where T : FrameworkElement, IDataContextChangedHandler<T>  
  7.     {  
  8.         public static readonly DependencyProperty InternalDataContextProperty =  
  9.             DependencyProperty.Register("InternalDataContext",  
  10.             typeof(Object), typeof(T), new PropertyMetadata(OnDataContextChanged));  
  11.   
  12.         public static void Bind(T control)  
  13.         {  
  14.             control.SetBinding(InternalDataContextProperty, new Binding());  
  15.         }  
  16.   
  17.         private static void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)  
  18.         {  
  19.             T control = (T)sender;  
  20.             control.OnDataContextChanged(control, e);  
  21.         }  
  22.     }  

如何使用:
在自定義control的構造函數中設置binding即可。參考的文檔沒有說清楚如何使用,我是看下邊的英文原版,才有的靈感,差點放棄了 by dacong

View Code
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=Relaxed


One 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 track changes.


Is your email address OK? You are signed up for our newsletters but your email 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 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 track changes. This becomes a problem in controls like the DataGrid control 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 something a 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 DataContext and also provide a method to call when this happens. That was easy enough. I createdIDataContextChangedHandler and 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 theFrameworkElement but 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 isobject, 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 implementsIDataContextChangedHandler, 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 theDataContext changes, 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 implementedIDataContextChangedHandler and then registered by calling Bind in our constructor.

需要補充的是, 這個功能在Silverlight 5中已經自帶。

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
GridView事件DataBinding,DataBound,RowCreated,Ro...
ZeroMQ
字節(jié)跳動的管理方式:context not control
SoundPool 播放音頻的時候在小米的手機上只播放一次,其它手機正常。
Android Sensors Development(HAL有參考價值)
人生在世亦如擺渡
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服