Являются ли "{Binding Path =.}" И "{Binding}" действительно равными
В моем проекте WPF у меня есть ListBox, который отображает элементы из коллекции List<string>
. Я хотел, чтобы текст этих элементов редактировался, поэтому я завернул каждую из них в ItemTemplate с помощью TextBox (возможно, это не лучший способ, но я новичок в 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", в соответствии с Microsoft:
[...] для привязки к текущему источнику может использоваться путь периода (.). Например, Text = "{Binding}" эквивалентен Text = "{Binding Path =.}"
Может ли кто-то пролить свет на это двусмысленное поведение?
EDIT: Кроме того, кажется, что {Binding Path=.}
не обязательно дает двустороннюю привязку, так как изменение текста и перемещение фокуса не обновляют базовый источник (тот же источник также показывает свойства и успешно изменен в элементе управления DataGrid). Я определенно что-то пропустил.
Ответы
Ответ 1
Предполагается, что точка исключения состоит в том, что вы не можете привязать к объекту привязки двухстороннюю привязку, поэтому она пытается помешать вам создать привязку, которая не ведет себя так, как вам хотелось бы. Используя {Binding Path=.}
, вы просто обманываете обработку ошибок.
(И это не неслыханно, что документация ошибочна или неточна, хотя мне очень нравится документация MSDN вообще, поскольку она обычно содержит важные моменты, которые вас интересуют)
Ответ 2
В документации указано, что {Binding}
эквивалентно {Binding Path=.}
. Однако это не эквивалентно {Binding Path}
, как вы набрали. Если вы включили свойство Path
, вы должны назначить его чему-то, будь то Path=.
или Path=OtherProperty
.
Ответ 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 - В чем разница между передачей по ссылке или передачей по значению?)
Однако я не понимаю, почему просто использование {Binding} не сработало (это вызвало исключение "Двухстороннее связывание требует исключения Path или XPath" )
Предположим теперь, что {Binding}
может использоваться для двусторонней привязки. Обычно {Binding}
создает ссылку на основе значения с datacontext, которая не позволяет обновлять datacontext.
В то время как {Binding Path=.}
создает ссылку на основе ссылки с областью памяти, на которую ссылается "Путь", которая позволяет обновлять значение через ссылку (в данном случае "точка" - текущий точечный текст).
Надеюсь, это поможет!