Reputation: 8816
In my WPF project, I have a ListBox that displays items from a List<string>
collection. I wanted to make the text of these items editable, so I wrapped each of them in an ItemTemplate with a TextBox (might not be the best way, but I'm new to WPF). I was having trouble simply binding the TextBoxes' Text property to the value of each item. I finally stumbled upon an example using a single dot or period for its Path property ({Binding Path=.}
):
<ListBox ItemsSource="{Binding ElementName=recipesListbox,Path=SelectedItem.Steps}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=.}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
However I don't understand why simply using {Binding}
didn't work.
It raised a "Two-way binding requires Path or XPath" exception, as according to Microsoft:
[...] a period (.) path can be used to bind to the current source. For example, Text="{Binding}" is equivalent to Text="{Binding Path=.}"
Could someone shed light on this ambiguous behavior?
EDIT: Moreover, it seems {Binding Path=.}
does not necessarily give two-way binding, as modifying the text and moving the focus does not update the underlying source (the same source has also properties displayed and successfully modified on a DataGrid control). I'm definitely missing something here.
Upvotes: 54
Views: 42931
Reputation: 185578
The point of the exception presumably is that you cannot two-way bind a binding-source itself, so it tries to prevent you from creating a binding which does not behave the way you would want it to. By using {Binding Path=.}
you just trick the error detection.
(Also it's not unheard of that documentation is erroneous or inaccurate, though i do like the MSDN documentation a lot in general as it usually does contain the crucial points one is interested in)
Upvotes: 34
Reputation: 89
In short, the difference between the two is analogous with the difference between the traditional pass by value and pass by reference. (FYR - What's the difference between passing by reference vs. passing by value?)
However I don't understand why simply using {Binding} didn't work (it raised a "Two-way binding requires Path or XPath" exception)
Lets assume here for now that {Binding}
can be used for two way binding. In general {Binding}
creates a value based link with datacontext which does not allow updating the datacontext.
Whereas {Binding Path=.}
creates reference based link with the memory area referenced by the 'Path' which allows updating the value through reference.(in this case 'dot' the current datacontext).
Hope this helps!
Upvotes: 8
Reputation:
These are not the same. If you bind this where ConsoleMessages is an ObservableCollection string with just {Binding} you get a "Two-way binding requires Path or XPath." exception where as {Binding Path=.} works. This is with 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>
My 2p worth...
Upvotes: 7
Reputation: 4852
The documentation states that {Binding}
is equivalent to {Binding Path=.}
. However it is not equivalent to {Binding Path}
as you have typed. If you include the Path
property, you must assign it to something, be it Path=.
or Path=OtherProperty
.
Upvotes: 23