为什么将 Window 的 DataContext 设置为 {Binding RelativeSource={RelativeSource Self}} 允许您将数据绑定到代码隐藏的属性?

Why does setting the DataContext of a Window to {Binding RelativeSource={RelativeSource Self}} allow you to databind to the properties of code-behind?

据我了解,将 DataContext 设置为控件本身将允许您使用数据绑定访问该控件的 属性 而无需指定 Source,因此设置Window{Binding RelativeSource={RelativeSource Self}}DataContext 应该只允许您将数据绑定到 Window class 中定义的属性,而不是代码隐藏中的属性因为代码隐藏文件只继承了Window class,而我在代码隐藏文件中定义的属性并不直接属于Window class。但是,当我这样做时,它神奇地允许我将数据绑定到我在代码隐藏文件中定义的属性。这是如何工作的?

是的,将控件的 DataContext 设置为自身允许您在 Binding.

中访问其属性
  • Code-Behind

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

    在 XAML 中创建一个 Binding 将自动 inherit this DataContext 作为 Source 用于绑定,如果它没有被覆盖,例如ItemsControl.

    中的项目设置为 DataContext

    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}}">
    

    BindingRelativeSource will set the Source 到 window 本身。如果您使用 AncestorType={x:Type Window}.

    ,情况也是如此

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

    cannot set multiple different sources 单次绑定。

    RelativeSource: mutually exclusive versus with ElementName and Source;

本质上,如果不设置 Source,您永远不会绑定,它是隐式或显式设置的。


如果指定 Window 作为来源,为什么 Binding 会起作用?你要明白,XAML文件和你的code-behind编译后是同一个class。它们都是在编译时合并的 partial 定义。你继承自 Window 是对的,但你对绑定的理解是错误的。如果我们谈论 class 继承,您是对的,通过 Window 引用访问派生的 MyWindow 将不允许您访问其属性,但绑定不能以这种方式工作。它们是 expressions loosley couple 依赖属性到被绑定的属性。它们只是 resolved at run-time,这意味着它们应用于 DataContext 的实际 run-time 类型 ,即 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.

您可以将任意 object 分配和切换为 DataContext,甚至是不同的类型。只要任何绑定的 Path 匹配任何 属性 值就会解析成功,否则会出现绑定错误。