WPF附加属性数据绑定

Dan*_*şar 63 wpf xaml binding attached-properties

我尝试使用附加属性绑定.但无法让它发挥作用.

public class Attached
{
    public static DependencyProperty TestProperty =
        DependencyProperty.RegisterAttached("TestProperty", typeof(bool), typeof(Attached),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Inherits));

    public static bool GetTest(DependencyObject obj)
    {
        return (bool)obj.GetValue(TestProperty);
    }

    public static void SetTest(DependencyObject obj, bool value)
    {
        obj.SetValue(TestProperty, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML代码:

<Window ...>
    <StackPanel local:Attached.Test="true" x:Name="f">
        <CheckBox local:Attached.Test="true" IsChecked="{Binding (local:Attached.Test), Mode=TwoWay, RelativeSource={RelativeSource Self}}" />
        <CheckBox local:Attached.Test="true" IsChecked="{Binding (local:Attached.Test), Mode=TwoWay}" />
    </StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)

和绑定错误:

System.Windows.Data Error: 40 : BindingExpression path error: '(local:Attached.Test)' property not found on 'object' ''StackPanel' (Name='f')'. BindingExpression:Path=(local:Attached.Test); DataItem='StackPanel' (Name='f'); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1')
Run Code Online (Sandbox Code Playgroud)

Ken*_*art 157

信不信由你,只需Path=在绑定到附加属性时添加并使用括号:

IsChecked="{Binding Path=(local:Attached.Test), Mode=TwoWay, RelativeSource={RelativeSource Self}}"
Run Code Online (Sandbox Code Playgroud)

此外,您的调用RegisterAttached应该将"Test"作为属性名称传递,而不是"TestProperty".

  • `RegisterAttached`调用应该传递"Test",而不是"TestProperty"作为属性名称. (9认同)
  • 为什么需要括号?一个人应该阅读什么参考知道这个神秘的东西? (5认同)
  • 我希望我可以多次投票.进行此更改后,请确保重建项目.我第一次忘了这么做,并认为Path =实际上没有用. (2认同)
  • 括号只是附加属性系统的“索引器”。这就是 WPF 区分附加属性和直接属性的方式。我想编译器会很困惑,无法尝试找出哪些属性已附加,哪些属性未附加,因此使用括号提供了该提示。如果您好奇,在幕后,WPF 实际上为附加属性创建一个 PropertyPath,如下所示:`new PropertyPath("(0)", new object[] { propertyName })`,假设 `propertyName` 是一个 `String` 。 (2认同)

Liv*_*ven 19

我更愿意将此作为对肯特答案的评论发布,但由于我没有足够的代表这样做...只是想指出,从WPF 4.5开始,Path=不再需要添加.但是,附加的属性名称仍然需要用括号括起来.

  • 即使使用 .NET 4.5 或 .NET 4.6,在绑定到 DataTriggers 中的附加属性时,如果没有 `Path=`,我也无法让它工作。 (2认同)