Почему этот простой сценарий привязки данных не работает?(связанный со списком)

StackOverflow https://stackoverflow.com/questions/458636

Вопрос

Я уже некоторое время ломаю голову над этим вопросом и на данный момент нахожусь в тупике.

Сценарий проблемы проще объяснить в виде кода, так что, надеюсь, он говорит сам за себя.Прежде всего, у меня есть приложение silverlight со следующим в XAML...

<UserControl x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Width="400" Height="300">

<UserControl.Resources>
    <DataTemplate x:Key="icTemplate">
        <ComboBox ItemsSource="{Binding StringsChild}" SelectedItem="{Binding SelectedItem}"/>
    </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <ItemsControl x:Name="ic" ItemTemplate="{StaticResource icTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

    <Button Click="Save" Grid.Row="1" Content="GO"/>
</Grid>

Мой исходный код выглядит следующим образом...(все написано в одном файле класса, чтобы вам было легко скопировать его в свой собственный проект и скомпилировать)

namespace SilverlightApplication2
{
    public partial class Page : UserControl
    {
        public ObservableCollection<SomeClass> StringsParent { get; set; } 

        public Page()
        {   
            InitializeComponent();
            StringsParent = new ObservableCollection<SomeClass>();
            ic.ItemsSource = StringsParent;
        }

        private void Save(object sender, RoutedEventArgs e)
        {
            SomeClass c = new SomeClass();
            c.StringsChild.Add("First");
            c.StringsChild.Add("Second");
            c.StringsChild.SetSelectedItem("Second");
            StringsParent.Add(c);
        }
    }

    public class SomeClass
    {
        public SelectableObservablecollection<string> StringsChild { get; set; }

        public SomeClass()
        {
            StringsChild = new SelectableObservablecollection<string>();
        }    
    }

    public class SelectableObservablecollection<T> : ObservableCollection<T>
    {
        public SelectableObservablecollection()
            : base()
        {

        }

        public void SetSelectedItem<Q>(Q selectedItem)
        {
            foreach (T item in this)
            {
                if (item.Equals(selectedItem))
                {
                    SelectedItem = item;
                    return;
                }
            }
        }

        private T _selectedItem;
        public T SelectedItem
        {
            get
            {
                return _selectedItem;
            }
            set
            {
                _selectedItem = value;
                OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem"));
            }
        }
    }
}

Итак, позвольте мне объяснить...Я намеревался написать общий способ создания ObservableCollection, который имеет Выбранный элемент свойство на нем, так что, например, когда я привязываю коллекцию к выпадающему списку, я могу привязать выпадающий список Выбранный элемент собственность к нему.

Однако по какой-то причине это, похоже, не работает, когда поле со списком эффективно вложено через ItemTemplate .Фактически у меня есть список списков, сценарий, который достаточно прост, чтобы я терялся в том, что не так.

Когда вы запустите код, вы увидите, что шаблонное поле со списком действительно выбирает правильные элементы, но оно никогда не устанавливается в SelectedItem, несмотря на привязку.

Я знаю, что это довольно многословно, но...есть идеи?

Большое спасибо

Это было полезно?

Решение

Выходные данные отладчика на самом деле дают вам подсказку к проблеме:

Система.Windows.Ошибка данных:Ошибка пути к BindingExpression: Свойство 'SelectedItem' не найдено в 'ExpressionElements.SomeClass' 'ExpressionElements.SomeClass' (хэш-код=49044892).Связывающее выражение:Path='SelectedItem' DataItem='ExpressionElements.SomeClass' (Хэш-код=49044892);целевой элемент - 'System.Windows.Элементы управления.Поле со списком' (Name=");целевым свойством является 'SelectedItem' (тип 'System.Объект')..

Поскольку контекст данных для шаблона является экземпляром класса SomeClass, все, что вам нужно сделать, это изменить привязку SelectedItem с SelectedItem на StringsChild.Выбранный элемент:

<DataTemplate x:Key="icTemplate">
    <ComboBox ItemsSource="{Binding StringsChild}" 
     SelectedItem="{Binding StringsChild.SelectedItem}"/>
</DataTemplate>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top