2016-12-05 64 views
0

我在UWP应用程序中有以下内容。请注意,我的元素来自DependencyObject,而不是来自Control,Panel等。但是当我调用测试方法MessWithBindings()时,绑定不起作用。 PropertyChanged方法会触发,但PropertyChangedEventHandler为null,所以它什么也不做。我应该直接设置事件处理程序吗?还是有另一个电话我错过了创建它?试图设置一个自定义的DependencyObject。显然缺少的东西

顺便提一句,我有BindWidth/BindHeight方法的FrameworkElement版本,而且这些方法工作得很好。

class WindowsElement: DependencyObject, INotifyPropertyChanged 
{ 
    public WindowsElement() 
    { 
    } 
    private double _Width { get; set; } 
    private double _Height { get; set; } 
    public double Width 
    { 
     get 
     { 
      return _Width; 
     } 
     set 
     { 
      if (_Width != value) 
      { 
       _Width = value; 
       OnPropertyChanged("Width"); 
      } 
     } 
    } 


    public double Height 
    { 
     get 
     { 
      return _Height; 
     } 
     set 
     { 
      if (_Height != value) 
      { 
       _Height = value; 
       OnPropertyChanged("Height"); 
      } 
     } 
    } 

    public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
     "Width", 
     typeof(double), 
     typeof(WindowsElement), 
     null); 

    public static readonly DependencyProperty HeightProperty = DependencyProperty.Register(
"Height", 
typeof(double), 
typeof(WindowsElement), 
null); 

    private double _ActualWidth { get; set; } 

    public double ActualWidth { 
     get 
     { 
      return _ActualWidth; 
     } 
     set 
     { 
      if (_ActualWidth != value) 
      { 
       _ActualWidth = value; 
       OnPropertyChanged("ActualWidth"); 
      } 
     } 
    } 

    private double _ActualHeight { get; set; } 

    public double ActualHeight { 
     get 
     { 
      return _ActualHeight; 
     } 
     set 
     { 
      if (_ActualHeight != value) 
      { 
       _ActualHeight = value; 
       OnPropertyChanged("ActualHeight"); 
      } 
     } 
    } 

    public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(
     "ActualWidth", 
     typeof(double), 
     typeof(WindowsElement), 
     null); 

    public static readonly DependencyProperty ActualHeightProperty = DependencyProperty.Register(
"ActualHeight", 
typeof(double), 
typeof(WindowsElement), 
null); 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    internal void SetBinding(DependencyProperty property, Binding b) 
    { 
     BindingOperations.SetBinding(this, property, b); 
    } 

    public static void MessWithBindings() 
    { 
     WindowsElement we1 = new WindowsElement(); 
     WindowsElement we2 = new WindowsElement(); 
     we1.BindWidth(we2); 
     we1.BindHeight(we2); 
     we2.Width = 12; 
     we2.ActualWidth = 13; 
     we2.ActualHeight = 666; 
     CommonDebug.LogLine(we1, we1.Width, we1.Height, we1.ActualWidth, we1.ActualHeight, we2, we2.ActualWidth, we2.ActualHeight); 
     CommonDebug.DoNothing(); 
    } 
} 


internal static class WindowsElementAdditions 
{ 
    public static void BindWidth(this WindowsElement bindMe, WindowsElement toMe) 
    { 
    Binding b = new Binding(); 
    b.Mode = BindingMode.OneWay; 
    b.Source = toMe.ActualWidth; 
    bindMe.SetBinding(WindowsElement.WidthProperty, b); 
    } 

    public static void BindHeight(this WindowsElement bindMe, WindowsElement toMe) 
    { 
    Binding b = new Binding(); 
    b.Mode = BindingMode.OneWay; 
    b.Source = toMe.ActualHeight; 
    bindMe.SetBinding(WindowsElement.HeightProperty, b); 
    } 
} 

回答

1

依赖属性的属性包装必须调用的DependencyObject的GetValueSetValue方法,例如

class WindowsElement : DependencyObject 
{ 
    public static readonly DependencyProperty WidthProperty = 
     DependencyProperty.Register(
      "Width", typeof(double), typeof(WindowsElement), null); 

    public double Width 
    { 
     get { return (double)GetValue(WidthProperty); } 
     set { SetValue(WidthProperty, value); } 
    } 
} 

它不能调用其他任何东西。当该属性由绑定(或样式设置器,一些其他来源)设置时,框架不调用属性包装器,但直接调用SetValue

为了得到内部通知关于改变的属性值,类应该注册一个PropertyChangedCallback通过PropertyMetadata

public static readonly DependencyProperty WidthProperty = 
    DependencyProperty.Register(
     "Width", typeof(double), typeof(WindowsElement), 
     new PropertyMetadata((double)0, WidthPropertyChanged)); 

private static void WidthPropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e) 
{ 
    WindowsElement element = (WindowsElement)o; 
    double width = (double)e.NewValue; 
    // update element here if necessary 
} 

依赖属性已经落实通知有关更改属性侦听器(如绑定)的机制值,因此在这里不需要执行INotifyPropertyChanged

+0

嗯,仍然没有工作;对ActualWidthPropertyChanged的调用不会触发对WidthPropertyChanged的调用。 –

+0

绑定的来源不是属性,而是包含属性的对象。该属性由绑定路径指定。 – Clemens

+0

更改太大,无法编辑我原来的问题,所以我在这里开始了一个新的:http://stackoverflow.com/questions/40976591/set-bindings-for-custom-dependencyobjects –