“Binding Path=.”和“Binding”真的相等吗

Posted

技术标签:

【中文标题】“Binding Path=.”和“Binding”真的相等吗【英文标题】:Are "Binding Path=." and "Binding" really equal“Binding Path=.”和“Binding”真的相等吗 【发布时间】:2011-07-26 04:07:59 【问题描述】:

在我的 WPF 项目中,我有一个 ListBox,它显示来自 List<string> 集合的项目。我想让这些项目的文本可编辑,所以我将它们中的每一个包装在一个带有 TextBox 的 ItemTemplate 中(可能不是最好的方法,但我是 WPF 新手)。我在简单地将 TextBoxes 的 Text 属性绑定到每个项目的值时遇到了麻烦。我终于偶然发现了一个使用单个点或句点作为其 Path 属性的示例 (Binding Path=.):

<ListBox ItemsSource="Binding ElementName=recipesListbox,Path=SelectedItem.Steps">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBox Text="Binding Path=."/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

但是我不明白为什么简单地使用Binding 不起作用。

它引发了“双向绑定需要 Path 或 XPath”异常,如 according to Microsoft:

[...] 句点 (.) 路径可用于绑定到当前源。例如,Text="Binding" 等价于 Text="Binding Path=."

有人能解释一下这种模棱两可的行为吗?

编辑:此外,似乎Binding Path=. 不一定提供双向绑定,因为修改文本和移动焦点不会更新底层源(同一源也显示属性并在 DataGrid 控件上成功修改)。我肯定在这里遗漏了一些东西。

【问题讨论】:

【参考方案1】:

异常的要点大概是您不能双向绑定绑定源本身,因此它会试图阻止您创建不符合您希望的行为方式的绑定。通过使用Binding Path=.,您只是欺骗了错误处理。

(虽然我确实非常喜欢 MSDN 文档,因为它通常包含人们感兴趣的关键点)

【讨论】:

+1:这是正确答案。 I just encountered这个现象我自己。 但是双向绑定仍然失败。它拒绝保存更改。如果您有 ObsColl 并执行 Path=。 Mode=TwoWay 绑定,添加到集合中工作正常。例如,更改索引 0 处的数字不会。如果您将数据网格绑定到它并指定数据网格文本列,它会拒绝使用 Path= 保存。 @user999999928:这就是我一直在说的:你只是欺骗错误处理。您犯了一个未检测到的错误,您仍然无法获得所需的绑定,因为您仍然绑定到无法检测到更改的源。【参考方案2】:

文档指出Binding 等同于Binding Path=.。但是,它等同于您键入的Binding Path。如果包含Path 属性,则必须将其分配给某个对象,无论是Path=. 还是Path=OtherProperty

【讨论】:

这是一个错字,现在已修复。 但是双向绑定仍然失败。它拒绝保存更改。如果您有 ObsColl 并执行 Path=。 Mode=TwoWay 绑定,添加到集合中工作正常。例如,更改索引 0 处的数字不会。如果将数据网格绑定到它并指定数据网格文本列,它会拒绝使用 Path= 保存。【参考方案3】:

这些不一样。如果在 ConsoleMessages 是 ObservableCollection 字符串的情况下仅使用 Binding 进行绑定,则会得到“双向绑定需要 Path 或 XPath”。 Binding Path=. 起作用的异常。这是 WPF 4.0...

    <ItemsControl x:Name="ConsoleOutput" ItemsSource="Binding ConsoleMessages, Mode=OneWay" MaxHeight="400">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBox Text="Binding Path=." BorderThickness="0" Margin="0" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

我的 2p 价值...

【讨论】:

【参考方案4】:

简而言之,两者的区别类似于传统的值传递和引用传递的区别。 (FYR - What's the difference between passing by reference vs. passing by value?)

但是我不明白为什么简单地使用 Binding 不起作用(它引发了“双向绑定需要 Path 或 XPath”异常)

现在让我们假设Binding 可以用于双向绑定。通常Binding 使用不允许更新数据上下文的数据上下文创建基于值的链接。

Binding Path=. 使用“路径”引用的内存区域创建基于引用的链接,允许通过引用更新值。(在这种情况下,“点”当前数据上下文)。

希望这会有所帮助!

【讨论】:

使用 ByRef 和 ByVal 至少让我了解了如何区分这两种绑定(使用 Path 和 w/o)。谢谢!

以上是关于“Binding Path=.”和“Binding”真的相等吗的主要内容,如果未能解决你的问题,请参考以下文章

WPF 绑定中的“Binding Path=.”是啥意思?

C# wpf 中 一个窗体中的texbox内容显示另一个窗体中的listview中的内容。如何实现

将DataTable数据绑定到DataGrid - 代码背后

Binding 和 x:Bind 之间的区别

SwiftUI 中的 @Binding 和 ForEach

WSDL 中的 <binding> 和 <portType> 有啥区别?