2016-12-05 1 views
0

Ich habe folgendes in einer UWP App. Beachten Sie, dass mein Element von DependencyObject abstammt, nicht von einem Control, Panel usw. Wenn ich jedoch die Testmethode MessWithBindings() aufruft, funktionieren die Bindungen nicht. Die PropertyChanged-Methode wird ausgelöst, der PropertyChangedEventHandler ist jedoch null, sodass nichts ausgeführt wird. Soll ich den Event-Handler irgendwie direkt einrichten? Oder gibt es einen anderen Anruf, den ich vermisse, der es schafft?Versuchen, ein benutzerdefiniertes DependencyObject einzurichten. Offensichtlich fehlt etwas

Übrigens habe ich FrameworkElement-Versionen der BindWidth/BindHeight-Methoden, und diese funktionieren gut.

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); 
    } 
} 

Antwort

1

Die Eigenschaft Wrapper einer Abhängigkeitseigenschaft muss der GetValue und SetValue Methoden des DependencyObject nennen, z.B.

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); } 
    } 
} 

und es darf nichts anderes als das anrufen. Wenn die Eigenschaft von einem Binding (oder einem Style-Setter, einigen anderen Quellen) festgelegt wird, ruft das Framework den Eigenschaftenwrapper nicht auf, sondern ruft direkt SetValue auf.

Um intern über eine geänderte Eigenschaftswert informiert zu werden, sollte die Klasse registriert eine PropertyChangedCallback über 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 
} 

Abhängigkeitseigenschaften bereits einen Mechanismus implementieren, die Zuhörer (zB Bindings) über geänderte Eigenschaft benachrichtigt Werte, daher muss hier INotifyPropertyChanged nicht implementiert werden.

+0

Hmmm, immer noch nicht funktioniert; Der Aufruf von ActualWidthPropertyChanged löst keinen Aufruf von WidthPropertyChanged aus. –

+0

Eine Quelle einer Bindung ist keine Eigenschaft, sondern das Objekt, das die Eigenschaft enthält. Die Eigenschaft wird durch den Pfad der Bindung angegeben. – Clemens

+0

Die Änderungen sind zu groß, um meine ursprüngliche Frage zu bearbeiten. Deshalb habe ich hier eine neue Frage gestartet: http://StackOverflow.com/questions/40976591/set-bindings-for-custom-dependencyobjects –

Verwandte Themen