【问题标题】:Silverlight detect when Dependency property has a Xaml bindingSilverlight 检测 Dependency 属性何时具有 Xaml 绑定
【发布时间】:2012-11-03 21:17:09
【问题描述】:

是否可以检测何时在 Silverlight 中的 DependencyProperty 上设置了 Xaml 绑定?

例如如果我有一个具有单个依赖属性的自定义用户控件和一个像这样声明的绑定:

public class MyControl : UserControl
{ 
   public static readonly DependencyProperty TestProperty = 
           DependencyProperty.Register("Test", 
              typeof(object), typeof(MyControl), 
              new PropertyMetadata(null));

   public object Test
   { 
       get { return GetValue(TestProperty); } 
       set { SetValue(TestProperty, value); } 
   }
}

<MyControl Test="{Binding APropInViewModel}>
</MyControl>

我可以在 MyControl 代码中改成这样吗?

// Ctor
public MyControl()
{ 
    TestProperty.BindingChanged += new EventHandler(...)
} 

例如我可以获得绑定通知吗?

注意:

这是为了解决 tricky order of precedence problem, described here 问题,因此仅在 DependencyPropertyChanged 处理程序中检查新值是行不通的 - 因为属性更改处理程序不会触发!

【问题讨论】:

  • 你为什么想让你的 observablecollection 成为一个 DP?你真的要在运行时替换它吗?
  • 如果您不打算替换整个集合,只需一个普通属性就足够了:绑定也可以使用它。并且集合中的更改将被拾取,因为它实现了INotifyCollectionChanged。再说一遍:你实际上不需要 DP 的可能性很高。
  • 所以也许你需要一个不同的集合模式。
  • 我在考虑一般问题:也许引用类型的属性通常不需要是 DP?原因是对于它们,我们通常不感兴趣将它们作为一个整体替换,而是更改它们的属性(它们是值类型的),或者它们的引用类型属性的属性(同样,它们是值类型的)等等下树。所以下面的策略似乎是合理的:(1)值类型的属性必须是 DP; (2) 引用类型的属性必须是普通属性,但从 DependencyObject 派生; (3) 这同样适用于递归。
  • 这个规则唯一的小例外似乎是一个集合:它必须实现INotifyCollectionChanged 而不是INotifyPropertyChanged,因为我们通过索引而不是名称访问它的子项。

标签: c# silverlight dependency-properties


【解决方案1】:

此绑定中的值可以更改。您可以使用 propertychanged 回调方法检测更改,该方法对于 Dependency 属性是静态的。

public static readonly DependencyProperty TestProperty =
       DependencyProperty.Register("Test",
          typeof(object), typeof(MyControl),
          new PropertyMetadata(null, TestChangedCallbackHandler));

    private static void TestChangedCallbackHandler(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        MyControl obj = sender as MyControl;

        Test = args.NewValue; 
    }

但是,这可能会导致以下事件侦听情况。如果您想监听此依赖属性的更改,请参阅此链接: Listen DepencenyProperty value changes

public void RegisterForNotification(string propertyName, FrameworkElement element, PropertyChangedCallback callback)
    {
        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);
    }

然后这样调用

this.RegisterForNotification("Test", this, TestChangedCallback);

【讨论】:

    猜你喜欢
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    相关资源
    最近更新 更多