2

I'm trying to translate this XAML code:

<Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}" />

Into this C# code:

var binding = new Binding("DataContext")
{
    RelativeSource = new RelativeSource {AncestorType = typeof(UserControl)}
};
var value = PropertyPathHelper.GetValue(binding);

The implementation of my PropertyPathHelper (modified from another thread) class is as follows:

public static class PropertyPathHelper
{
    public static object GetValue(Binding binding)
    {

        BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding);
        return _dummy.GetValue(Dummy.ValueProperty);
    }

    private static readonly Dummy _dummy = new Dummy();

    private class Dummy : DependencyObject
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null));
    }
}

Either my Binding declaration isn't right, or my PropertyPathHelper implementation isn't right, but I don't know which, because at runtime, "var value" comes out as null. Even if I pass a non-existent name into the constructor of Binding.

The binding works fine if I do it in XAML, but I have to do it in the codebehind. In case it's not clear, I'm trying to get the actual value of the DataContext of this view's first ancestor, which is of type UserControl.

What am I doing wrong?

  • How is this supposed to work, when the Dummy instance does apparently not have an ancestor ot type UserControl? Please let us know what you are actually trying to achieve. – Clemens Apr 16 '20 at 10:06
  • I'm trying to get the value of the DataContext of the view that my view is a part of. My view inherits from RadTabItem (from a third-party provider), and is contained inside another view which inherits from UserControl. – Graham Downs Apr 16 '20 at 10:16
  • Sorry, but that is not enough detail. Besides that, the DataContext property supports value inheritance, meaning the your view's DataContext equals that of its parent element, unless you explicity overwrite it. – Clemens Apr 16 '20 at 10:19

1 Answers1

0

I found a much more elegant way of achieving my goals... and it actually works.

First, in the XAML of my view, I added the following attribute:

Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

Then I found I could just grab what I need with the following code in the codebehind:

var v = this.Tag as FrameworkElement;
var vm = v.DataContext as MyViewModel; //The ViewModel of the parent view, not the current one

Thank you for your questions, @Clemens. In a roundabout way, you helped me think about my problem differently!

  • 2
    As a note, if you don't check the result for null, don't use the `as` operator. Use a type cast instead: `var v = (FrameworkElement)Tag;` – Clemens Apr 16 '20 at 10:39