В комбинированном ящике с источником элементов представления коллекции не обновляется элемент поля выбора при изменении модели. - PullRequest
1 голос
/ 29 апреля 2010

Извините за ранее длительный пост. Вот мое краткое (!) Описание.

Я связываю представление коллекции с выпадающим списком в качестве itemsSource, а также связываю его выделенное значение со свойством из моей модели представления. Я должен оставить IsSynchronizedWithCurrentItem = "False".

Я изменяю список источников для представления, а затем обновляю представление. Измененные (добавленные, удаленные, отредактированные) элементы правильно отображаются в списке элементов в комбинированном списке Но проблема с выбранным элементом. Когда я изменяю его свойство, которое также является путем отображения элемента комбинации, измененное значение свойства не отражается обратно в поле выбора в комбинации. Если открыть раскрывающийся список со списком, он правильно отображается в списке элементов, но не в поле выбора.

Теперь, если я изменю тег combobox на Listbox в моем XAML (сохраняя все атрибуты без изменений), то когда значение свойства displaymember выбранного элемента будет обновлено, изменения отразятся обратно на выбранном элементе списка.

Почему эта проблема?

Просто к вашему сведению:

  1. Моя модель просмотра имеет свойства EmployeeCollectionView и SelectedEmployeeId, которые связаны со списком как ItemsSource и SelectedValue, соответственно. Эта виртуальная машина реализует интерфейс INotifyPropertyChanged.

  2. Мой основной класс сотрудников (список которых является источником для EmployeeCollectionView) - это просто класс Model без INotifyPropertyChanged.

  3. DisplayMemberPath является свойством «Имя» сотрудника класса Модели. Я изменяю это некоторым способом и ожидаю, что поле выбора со списком обновит значение.

  4. Я попытался обновить свой SelectedEmployeeId, установив его в 0 (где он правильно выбирает фиктивную «Выбрать все -» запись сотрудника из itemsSource) и вернул старое выбранное значение. Но бесполезно. Старое значение возвращает меня к старому лейблу. В коллекции предметов есть последняя запись.

  5. Когда я делаю IsEditable = True в поле со списком, перед обновлением представления и после обновления я делаю IsEditable = False, тогда все работает правильно!

Но это патч и не нужен.

Thx

Винит Санхе

1 Ответ

0 голосов
/ 29 апреля 2010

Ваши баллы № 2 и № 3 - вот почему это не работает. Когда в поле со списком выбран элемент, он отображает в поле свойство Employee.Name. В # 2 вы заявляете, что Employee не реализует INotifyPropertyChanged, а в # 3 вы меняете имя и ожидаете его обновления в ComboBox. Но ComboBox не знает, что свойство изменилось, поэтому его отображаемое значение не изменится.

Я собрал очень простой пример, который продемонстрирует. Если вы закомментируете событие PropertyChanged, вы заметите, что нажатие кнопки больше не влияет на пользовательский интерфейс.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <ComboBox ItemsSource="{Binding}" DisplayMemberPath="Name" SelectedIndex="0" Width="150" Height="25" />
        <Button Content="Change" Width="75" Height="25" Click="button_Click"/>
    </StackPanel>
</Window>

И код позади ...

public partial class MainWindow : Window
{

    private ObservableCollection<Thing> things;
    private Queue<string> words;

    public MainWindow()
    {

        // some dummy data
        string text = "Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat sed diam voluptua";
        words = new Queue<string>(text.Split(' '));

        things = new ObservableCollection<Thing>();
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });

        DataContext = things;

        InitializeComponent();

    }

    private void button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        things[0].Name = words.Dequeue();
    }

}
...