The following XAML produces a run-time Binding error when I click on an item in the ListBox:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<x:Array x:Key="strings" Type="{x:Type sys:String}">
<sys:String>one</sys:String>
<sys:String>two</sys:String>
<sys:String>three</sys:String>
<sys:String>four</sys:String>
</x:Array>
</Window.Resources>
<Grid>
<ListBox
DataContext="{StaticResource strings}"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
SelectedValuePath="{Binding /Length}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Margin" Value="0,0,4,0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Row 0 -->
<Label Grid.Column="0" Grid.Row="0">String:</Label>
<TextBlock
Grid.Column="1"
Grid.Row="0"
Text="{Binding}"/>
<!-- Row 1 -->
<Label Grid.Column="0" Grid.Row="1">Length:</Label>
<TextBlock
Grid.Column="1"
Grid.Row="1"
Text="{Binding Length, Mode=Default}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
This is the run-time Binding error message:
System.Windows.Data Error: 39 : BindingExpression path error: ‘3’ property not found on ‘object’ ”String’ (HashCode=1191344027)’. BindingExpression:Path=3; DataItem=’String’ (HashCode=1191344027); target element is ‘ListBox’ (Name=”); target property is ‘NoTarget’ (type ‘Object’)
I would like the selected value of the ListBox to be the Length of the selected String object. What is wrong with my SelectedValuePath Binding syntax? Are there any related issues with IsSynchronizedWithCurrentItem?
Short answer
Replace
with
Long answer
SelectedValuePath is a string that gives the path from an object to the selected value. By writing
SelectedValuePath="{Binding /Length}"you are binding SelectedValuePath (not SeletedValue) to the “Length” property of the selected item, so if the length of the selected item is 3 then the value of the SelectedValuePath property is set to the string “3”. Then WPF tries to compute SelectedValue by finding a property named “3” on the string. Since the string object doesn’t have a property named “3” you get the error.You might think that
SelectedValue={Binding /Length}"would do the trick, and indeed it does express the concept of what you are actually trying to do. But it does not actually work becauseSelectorhas code that overwritesSelectedValuewheneverSelectedItemchanges.Another way to look at this is that setting
SelecteValuePathto the value “abcd” is effectively equivalent to settingSelectedValueto"{Binding /abcd}"(but only if IsSynchronizedWithCurrentItem=”true”).