Bruno Assis
Bruno Assis

Reputation: 1006

Bind XAML element to UserControl using ElementName

I have the following scenario and hierarchy of XAML elements in my page:

<Page> ....
 <StackPanel> ...
     <Grid> ....
       <StackPanel>
         <uc:MyUserControl
             ReferencedButton={Binding ElementName=RightButton} />
              <Button x:Name="RightButton" Click="{x:Bind ViewModel.OpenFlyout}" Content="Clickme" />
       </StackPanel>
  ......

Then the code behind from 'MyUserControl'

    public UIElement ReferencedButton
    {
        get { return (UIElement)GetValue(ReferencedButtonProperty); }
        set { SetValue(ReferencedButtonProperty, value); }
    }

    public static readonly DependencyProperty ReferencedButtonProperty =
        DependencyProperty.Register(nameof(ReferencedButton), typeof(UIElement), typeof(MyUserControl), null);

So far so good, however I was expecting that in my code behind, the 'ReferencedButton' property would be filled with a reference to the 'RightButton' button. However it always returns null.

I even tried:

{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, ElementName=RightButton}

I know it is possible to bind the element, because I got the example from a DevExpress component, but still without any success.

I am following the suggestions/rules from the following docs:

Binding ElementName

XAML Namescopes

p.s: I know that I can pass the reference to the button in my code behind however I would like to do this through XAML itself.

Upvotes: 0

Views: 318

Answers (1)

Bruno Assis
Bruno Assis

Reputation: 1006

It turns out that I needed to use a PropertyChangedCallback to make it work. So the solution is as below:

public static readonly DependencyProperty ReferencedButtonProperty=
        DependencyProperty.Register(nameof(ReferencedButton),
                typeof(UIElement),
                typeof(MyUserControl),
                new PropertyMetadata(default(UIElement),
                new PropertyChangedCallback(PlacementCallBack)));

and in the code behind of my control I can access and set the value by implementing the PlacementCallBack like this:

        public static void PlacementCallBack(object sender, DependencyPropertyChangedEventArgs e)
        {
            var myuserControl = sender as MyUserControl;
            myuserControl.ReferencedButton = e.NewValue as UIElement;
        }

The object DependencyPropertyChangedEventArgs contains two propeties NewValue and OldValue, they hold the old and new values of the previous object set.

Upvotes: 1

Related Questions