Замена ItemsSource ListView без потери SelectedItem - PullRequest
1 голос
/ 13 августа 2010

Я связываю данные ListView с коллекцией, которая происходит из сервисного уровня.В ответ на события модель представления, связанная с ListView, обновляет данные ListView.Чтобы получить обновленные данные, виртуальная машина извлекает новый экземпляр коллекции из сервисного уровня.Элементами в этой коллекции являются Equals (), но не ReferenceEquals () для эквивалентных элементов в ранее возвращенной коллекции.

Можете ли вы порекомендовать подход, который позволяет избежать недостатков подходов, указанных ниже, но при этом позволяет виртуальной машине включатьэти данные в ListView, не заставляя ListView потерять свой SelectedItem?

Спасибо,
Бен


Простой подход (просмотр кода модели; SelectedItem и ItemsSource ListView привязаны к идентично связанным свойствам в виртуальной машине):

var selectedItem = SelectedItem;
ItemsSource = service.GetData();
SelectedItem = Accounts.SingleOrDefault(x => x.Equals(selectedItem));

Этот подход кажется безобразным.Сюда также входит сброс SelectedItem - потенциальная проблема, если изменение SelectedItem приводит к изменению редактирования детали в форме основной детали.(Установка ItemsSource приводит к очистке SelectedItem, поэтому он переустанавливается в последней строке.)

Другой подход - написание адаптера, который загружает ObservableCollection <> с прокси-объектами, указывающими на данные, возвращаемые изначальный вызов уровня обслуживания.Каждый раз, когда обновленные данные извлекаются из сервисного уровня, прокси-объекты обновляются, чтобы указывать на вновь полученные объекты.Таким образом, нет необходимости сбрасывать ListSource ItemsSource для обновления ListView (он остается связанным с тем же ObservableCollection <>), что означает, что SelectedItem не будет сброшен.Недостатком этого подхода является количество кода.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2010

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

0 голосов
/ 15 сентября 2010

хмм ... как насчет этого:

Зарегистрируйте обработчики событий для SelectionChanged и DataContextChanged в ListView:

<ListView Name="listView" SelectionChanged="listView_SelectionChanged" DataContextChanged="listView_DataContextChanged" />

В обработчике SelectionChanged сохраните SelectedItem в теге ListView

private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    (sender as ListView).Tag = (sender as ListView).SelectedItem;
}

Как только DataContext для ListView изменился, оцените последний SelectedItem, который был сохранен в теге, относительно новой коллекции и установите новый элемент из этой коллекции:

    private void listView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        List<CustomClass> newList = e.NewValue as List<CustomClass>;
        if (newList != null && (sender as ListView).Tag != null)
        {
            foreach (CustomClass cClass in newList)
                if (cClass.Equals((sender as ListView).Tag as CustomClass))
                    (sender as ListView).SelectedItem = cClass;
        }
    }
...