Why does binding fail when binding a child element to another element when the parent completes successfully?

Let's say I have two classes that can reference a third user interface object (in this example, a button).

In addition, the parent class may contain an element of the child class.

If both are associated with the same control, then in the same way, the child will fail, but the parent is the successor.

Is this a bug in WPF?




Parent:

class MyFrameworkElement : FrameworkElement { // A depenedency property that will contain a child element sub-element private static readonly DependencyProperty ChildElementProperty = DependencyProperty.Register("ChildElement", typeof(MyChildElement), typeof(MyFrameworkElement), new PropertyMetadata()); [Category("ChildProperties")] public MyChildElement ChildElement { set { SetValue(ChildElementProperty, value); } get { return (MyChildElement)GetValue(ChildElementProperty); } } // Now, a reference to some other control, in this case we will bind a button to it! public UIElement ButtonReferenceInParent { get { return (UIElement)GetValue(ButtonReferenceInParentProperty); } set { SetValue(ButtonReferenceInParentProperty, value); } } // Using a DependencyProperty as the backing store for ButtonReferenceInParent. This enables animation, styling, binding, etc... public static readonly DependencyProperty ButtonReferenceInParentProperty = DependencyProperty.Register("ButtonReferenceInParent", typeof(UIElement), typeof(MyFrameworkElement), new UIPropertyMetadata(null)); 



And then the child:

 public class MyChildElement : FrameworkElement { public UIElement ButtonReferenceInChild { get { return (UIElement)GetValue(ButtonReferenceInChildProperty); } set { SetValue(ButtonReferenceInChildProperty, value); } } public static readonly DependencyProperty ButtonReferenceInChildProperty = DependencyProperty.Register("ButtonReferenceInChild", typeof(UIElement), typeof(MyChildElement), new UIPropertyMetadata(null)); } 

OK -

Now say that I add them to my XAML as follows:

 <Grid> <my:MyFrameworkElement x:Name="ParentName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ButtonReferenceInParent="{Binding ElementName=buttonisme}"> <my:MyFrameworkElement.ChildElement> <my:MyChildElement x:Name="ChildName" ButtonReferenceInChild="{Binding ElementName=buttonisme}"/> </my:MyFrameworkElement.ChildElement> </my:MyFrameworkElement> <Button x:Name="buttonisme" Click="buttonisme_Click" /> </Grid> 

Why does binding work on the parent, but then fail for the child when I use the EXACT same notation?




Here is my test code ...

  Console.WriteLine("Parent button reference is {0}", ParentName.ButtonReferenceInParent); if (ChildName.ButtonReferenceInChild == null) { Console.WriteLine("Child button reference is null!"); } else { Console.WriteLine("Child button is {0}", ChildName.ButtonReferenceInChild); } 

And here is the test result ...

Parent Button Link - System.Windows.Controls.Button

Link to the child button null!

+2
wpf binding xaml
01 Oct
source share
2 answers

The short answer to the long question is that Microsoft does not expect you to exit FrameworkElement without doing a bit of plumbing.

By simply concluding, it splits the logical tree, which is used when binding by the name of the element.

You may also have to drop the visual tree and overload the layout / dimension elements of the structure element. (We do not do this here, since we are not visual in this example.)

In this particular case, we need to add any children of your object to the logical tree or break the ability to bind children.

A good example of whoever solved this here

Information on overriding the logical tree here

In any case, the code needed to fix this SIMPLE example was based only on the logical tree (since the child is not really visual.)

Adding this function and changing the dependency property does the binding work.

  private static readonly DependencyProperty ChildElementProperty = DependencyProperty.Register("ChildElement", typeof(MyChildElement), typeof(MyFrameworkElement), new PropertyMetadata(OnChildElementChanged)); private static void OnChildElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MyFrameworkElement control = d as MyFrameworkElement; if (e.OldValue != null) { control.RemoveLogicalChild(e.OldValue); } control.AddLogicalChild(e.NewValue); } 
+5
Oct 10
source share

Firstly, when you install xaml as follows:

 <my:MyFrameworkElement x:Name="ParentName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ButtonReferenceInParent="{Binding ElementName=buttonisme}"/> <my:MyChildElement x:Name="ChildName" ButtonReferenceInChild="{Binding ElementName=buttonisme}"/> 

It works. I did this because I suspect that the visual vertical search is up to find the name of the element you are using in the binding.

I'm still figuring out how binding can be successful in your nested script. But perhaps this may give you some hint ...

-one
01 Oct '12 at 10:21
source share



All Articles