Reputation: 5348
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
?
Upvotes: 2
Views: 3605
Reputation: 62929
Short answer
Replace
SelectedValuePath="{Binding /Length}"
with
SelectedValuePath="Length"
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 because Selector
has code that overwrites SelectedValue
whenever SelectedItem
changes.
Another way to look at this is that setting SelecteValuePath
to the value "abcd" is effectively equivalent to setting SelectedValue
to "{Binding /abcd}"
(but only if IsSynchronizedWithCurrentItem="true").
Upvotes: 5