为什么编译绑定不能使用依赖属性,而经典绑定可以?

Why don't compiled bindings work with dependency properties, but classic bindings do?

我试图在我编写的自定义控件中从 dependency property 设置绑定,但我注意到绑定没有正确更新。我应该注意,我只是将 绑定到 属性.

属性 是相当标准的东西,像这样:

public bool HasText
{
    get => (bool)GetValue(HasTextProperty);
    private set => SetValue(HasTextProperty, value);
}

public static readonly DependencyProperty HasTextProperty = DependencyProperty.Register(
    nameof(HasText), typeof(bool), typeof(TextEditor), new PropertyMetadata(false));

现在,我首先尝试使用已编译的绑定,但失败了(它没有显示任何错误,但就是无法正常工作):

<controls:TextEditor x:Name="SomeTextEditor"/>
<controls:SomeControl IsEnabled="{x:Bind SomeTextEditor.HasText, Mode=OneWay}"/>

然后我尝试使用经典绑定,效果非常好:

<controls:TextEditor x:Name="SomeTextEditor"/>
<controls:SomeControl IsEnabled="{Binding ElementName=SomeTextEditor, Path=HasText}"/>

现在,我不得不说我不确定为什么会这样。 dependency property 内置了对通知的支持,否则经典绑定也无法正常工作。而且我没有忘记 x:Bind 默认为 Mode=OneTime,但即使在手动将其设置为 Mode=OneWay 之后它仍然无法正常工作。

有什么想法吗?我很可能在这里遗漏了一些明显的东西。

谢谢!

在 XAML 编译时,{x:Bind} 被转换为将从数据源上的 属性 获取值的代码,并将其设置在标记中指定的 属性 上。

指定的x:Name成为字段的名称,在处理XAML时在底层代码中创建,field 持有对象的引用。

如果使用x:Bind绑定x:Name字段,IsEnabled将不会像下面的代码一样获取可用值。这就是以下内容不起作用的原因。

<controls:SomeControl IsEnabled="{x:Bind SomeTextEditor.HasText, Mode=OneWay}"/>