silverlight屬性改變事件通知

  • 2019 年 10 月 10 日
  • 筆記

工作中遇到silverlight本身沒有提供的某些屬性改變事件,但又需要在屬性改變時得到通知,Google搬運stack overflow,原地址

 /// 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("Text", this.txtMain,(d,e)=>MessageBox.Show("Text changed"));  RegisterForNotification("Value", this.sliderMain, (d, e) => MessageBox.Show("Value changed"));

更正:以上方法可能會造成回調方法callback記憶體泄漏,改為封裝一個方法再調用callback

        /// <summary>          /// 監聽任意依賴屬性值改變事件的輔助方法          /// </summary>          /// <param name="element"></param>          /// <param name="propertyName"></param>          /// <param name="callback"></param>          public static void ListenForChange(FrameworkElement element, string propertyName, PropertyChangedCallback callback)          {              var b = new Binding(propertyName) { Source = element };              var prop = DependencyProperty.RegisterAttached("ListenAttached" + propertyName, typeof(object), typeof(FrameworkElement), new PropertyMetadata(new WeakPropertyChangedCallback(callback).PropertyChangedCallback));              element.SetBinding(prop, b);          }            /// <summary>          /// 解決ListenForChange導致的記憶體泄漏:          /// 避免DependencyProperty.RegisterAttached中元數據對PropertyChangedCallback的引用導致的記憶體泄漏          /// 但會導致WeakPropertyChangedCallback對象本身的泄漏,WeakPropertyChangedCallback對象本身不大,可以忽略          /// 即:以WeakPropertyChangedCallback對象的記憶體泄漏(很小) >>>===>>> 替代PropertyChangedCallback所在對象的記憶體泄漏(可能很大)          ///          /// TODO:暫時未找到其他的方式, DependencyProperty.RegisterAttached、PropertyMetadata缺少相關的清除方法          /// silverlight缺少BindingOperations.ClearBinding方法          /// </summary>          class WeakPropertyChangedCallback          {              private WeakReference callback;              public WeakPropertyChangedCallback(PropertyChangedCallback callback)              {                    this.callback = new WeakReference(callback);              }                /// <summary>              /// 轉發到callback              /// </summary>              /// <param name="d"></param>              /// <param name="e"></param>              public void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)              {                  if (callback.IsAlive)                  {                      var cb = callback.Target as PropertyChangedCallback;                      if (cb != null)                          cb(d, e);                  }              }          }