0

这是此处问题的延续:尝试设置自定义 DependencyObject。显然漏掉了什么。编辑原始问题是不切实际的;变化太大。所以我开始一个新的问题。

我正在尝试在我的 UWP 应用程序中设置自定义 DependencyObjects 之间的绑定。相关代码如下。我看到对 ActualWidthPropertyChanged 的​​调用,但它们没有触发对 WidthPropertyChanged 的​​任何调用。我错过了什么?

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

    private static void WidthPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
      WindowsElement element = (WindowsElement)o;
      double width = (double)e.NewValue;
      CommonDebug.LogLine("WPC", element, o, width);
      element.Width = width;
    }

   private static void ActualWidthPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
     {
       WindowsElement element = (WindowsElement)o;
       double width = (double)e.NewValue;
       CommonDebug.LogLine("AWPC", o, e, width, element.Width);
       element.ActualWidth = width;
     }
     public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
        "Width",
        typeof(double),
        typeof(WindowsElement),
       new PropertyMetadata((double)0, WidthPropertyChanged));

      public double ActualWidth {
        get
          {
            return (double)GetValue(ActualWidthProperty);
          }
        set
            {
              SetValue(ActualWidthProperty, value);
            }
        }


    public static readonly DependencyProperty ActualWidthProperty =  
      DependencyProperty.Register(
        "ActualWidth",
        typeof(double),
        typeof(WindowsElement),
        new PropertyMetadata((double)0, ActualWidthPropertyChanged));


    public static void MessWithBindings()
    {
        WindowsElement we1 = new WindowsElement();
        WindowsElement we2 = new WindowsElement();
        var b = new Binding
          {
            Source = we2,
            Path = new PropertyPath("ActualWidth")
          };

        BindingOperations.SetBinding(we1, WindowsElement.WidthProperty, b);
        we2.ActualWidth = 13;
        CommonDebug.LogLine(we1, we1.Width,  we1.ActualWidth, we2, we2.Width, we2.ActualWidth);
    }
}
4

2 回答 2

1

我看到对 ActualWidthPropertyChanged 的​​调用,但它们没有触发对 WidthPropertyChanged 的​​任何调用。我错过了什么?

要解决这个问题,您需要在源对象上实现 INotifyPropertyChanged 接口,以便源可以报告更改。

请看以下代码:

class WindowsElement : DependencyObject, INotifyPropertyChanged
{
    public WindowsElement()
    {
    }

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

    private static void WidthPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        WindowsElement element = (WindowsElement)o;
        double width = (double)e.NewValue;
        CommonDebug.LogLine("WPC", element, o, width);
        //element.Width = width;
        element.RaisedPropertyChanged("Width");
    }

    private static void ActualWidthPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        WindowsElement element = (WindowsElement)o;
        double width = (double)e.NewValue;
        CommonDebug.LogLine("AWPC", o, e, width, element.Width);
        //element.ActualWidth = width;
        element.RaisedPropertyChanged("ActualWidth");
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisedPropertyChanged(string PropertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
    }

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

    public double ActualWidth
    {
        get
        {
            return (double)GetValue(ActualWidthProperty);
        }
        set
        {
            SetValue(ActualWidthProperty, value);
        }
    }

    public static readonly DependencyProperty ActualWidthProperty = DependencyProperty.Register(
        "ActualWidth",
        typeof(double),
        typeof(WindowsElement),
        new PropertyMetadata((double)0, ActualWidthPropertyChanged));

    public static void MessWithBindings()
    {
        WindowsElement we1 = new WindowsElement();
        WindowsElement we2 = new WindowsElement();
        var b = new Binding
        {
            Source = we2,
            Path = new PropertyPath("ActualWidth")
        };

        BindingOperations.SetBinding(we1, WindowsElement.WidthProperty, b);
        we2.ActualWidth = 13;
        CommonDebug.LogLine(we1, we1.Width, we1.ActualWidth, we2, we2.Width, we2.ActualWidth);
    }
}
于 2016-12-06T08:25:23.193 回答
0

不知道为什么在 UWP 中,从一个依赖属性到另一个的单向绑定不会自动更新目标属性(就像在 WPF 中那样)。

但是,您可以简单地反转 Binding 的方向并使其双向:

var b = new Binding
{
    Source = we1,
    Path = new PropertyPath("Width"),
    Mode = BindingMode.TwoWay
};

BindingOperations.SetBinding(we2, WindowsElement.ActualWidthProperty, b);
we2.ActualWidth = 13;
于 2016-12-06T11:38:53.497 回答