Home > Back-end >  Why does setting the DataContext of a Window to {Binding RelativeSource={RelativeSource Self}} allow
Why does setting the DataContext of a Window to {Binding RelativeSource={RelativeSource Self}} allow

Time:04-04

According to my understanding, setting the DataContext to a control itself will allow you to access the property of that control using data binding without specifying the Source, so setting the DataContext of a Window to {Binding RelativeSource={RelativeSource Self}} should only allow you to data bind to the properties defined in the Window class, not the ones in the code-behind because the code-behind file only inherited the Window class, and the properties I defined in the code-behind file don't directly belong to the Window class. However, when I do it, it magically allows me to data bind to the properties I defined in the code-behind file. How does this work?

CodePudding user response:

Yes, setting the DataContext of a control to itself allows you to access its properties in a Binding.

  • Code-Behind

    public MyWindow()
    {
       DataContext = this;
       InitializeComponent();
    }
    

    Creating a Binding in XAML will automatically inherit this DataContext as Source for binding if it is not overridden e.g. an item is set as DataContext in an ItemsControl.

    Data context is a concept that allows elements to inherit information from their parent elements about the data source that is used for binding, as well as other characteristics of the binding, such as the path. [...]

  • XAML

    <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            x:Class="MyWpfApp.MyWindow"
         ...
            DataContext="{Binding RelativeSource={RelativeSource Self}}">
    

    The RelativeSource will set the Source of the Binding to the window itself. The same would be true, if you would use AncestorType={x:Type Window}.

    Gets or sets the binding source by specifying its location relative to the position of the binding target.

    You cannot set multiple different sources on a single binding.

    RelativeSource: mutually exclusive versus with ElementName and Source;

In essence, the you never bind without setting a Source, it is set implicitly or explicitly.


Why does the Binding work then, if you specify a Window as source? You have to understand, that the XAML file and your code-behind are one and the same class after compilation. They are both partial definitions that are merged on compilation. You are right that you inherit from Window, but your understanding of bindings is wrong. If we talk about class inheritance, you are right, accessing a derived MyWindow through a Window reference would not allow you to access its properties, but bindings do not work this way. They are expressions that loosley couple dependency properties to properties being bound. They are only resolved at run-time, which means they are applied to the actual run-time type of the DataContext, which is MyWindow.

Defers a property value to be a data-bound value, creating an intermediate expression object and interpreting the data context that applies to the element and its binding at run time.

You could assign and switch any arbitrary object as DataContext even of different types. As long as the Path of any binding matches any property value it will be resolved successfully, otherwise there will be a binding error.

  • Related