Попытка получить лучшее понимание SelectedValuePath и IsSynchronizedWithCurrentItem - PullRequest
1 голос
/ 17 марта 2010

Следующий XAML выдает ошибку привязки во время выполнения, когда я щелкаю элемент в 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>

Это сообщение об ошибке привязки во время выполнения:

System.Windows.Data Ошибка: 39: Ошибка пути BindingExpression: свойство '3' не найдено в 'object' '' String '(HashCode = 1191344027)'. BindingExpression: Path = 3; DataItem = 'String' (HashCode = 1191344027); целевым элементом является ListBox (Name = ''); Свойство target - «NoTarget» (тип «Объект»)

Я бы хотел, чтобы выбранное значение ListBox равнялось длине выбранного String объекта. Что не так с моим синтаксисом SelectedValuePath Binding? Есть ли какие-либо проблемы с IsSynchronizedWithCurrentItem?

1 Ответ

4 голосов
/ 17 марта 2010

Краткий ответ

Заменить

SelectedValuePath="{Binding /Length}"

с

SelectedValuePath="Length"

Длинный ответ

SelectedValuePath - это строка, которая указывает путь от объекта к выбранному значению. Написав SelectedValuePath="{Binding /Length}", вы связываете SelectedValuePath (не SeletedValue ) со свойством «Длина» выбранного элемента, поэтому, если длина выбранного элемента равна 3, тогда значение свойство SelectedValuePath устанавливается в строку «3». Затем WPF пытается вычислить SelectedValue , найдя в строке свойство с именем «3». Поскольку строковый объект не имеет свойства с именем «3», вы получите ошибку.

Вы можете подумать, что SelectedValue={Binding /Length}" сделает свое дело, и действительно, оно действительно выражает концепцию того, что вы на самом деле пытаетесь сделать. Но на самом деле это не работает, потому что Selector имеет код, который перезаписывает SelectedValue всякий раз, когда SelectedItem изменяется.

Другой способ взглянуть на это состоит в том, что установка SelecteValuePath в значение «abcd» фактически эквивалентна установке SelectedValue в "{Binding /abcd}" (но только если IsSynchronizedWithCurrentItem = "true").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...