CollectionViewSource CurrentItem

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

<ListView  
      ItemsSource="{Binding Projects.View}" 
      IsSynchronizedWithCurrentItem="True"
      SelectedItem="{Binding SelectedProject, Mode=TwoWay}">

Я использую сеттер для SelectedProject для облегчения модульного тестирования, и CurrentItem не кажется настраиваемым, насколько я можете наблюдать. Мне также нужно привести его к правильному объекту, когда я хочу его использовать. OTOH,если SelectedProject является избыточным, тогда я бы показал ему то же уважение, что и любая другая избыточность, и удалил бы его.

Итак, как вы обычно справляетесь с текущим элементом при использовании CollectionViewSource?

3 ответов


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

CollectionViewSource.GetDefaultView(Projects.View).CurrentItem as Project

просто для взаимодействия с текущим проектом. Я ценю ясность над "встроенным". Кроме того, CurrentItem доступен только для чтения, поэтому, если вы когда-либо захотите выбрать элемент в ViewModel, это будет невозможно.


вы должны понимать, что SelectedItem из ListView не зависит от ItemsSource. Если вы используете CollectionViewSource или список или массив, выбранный элемент всегда будет представлять элемент этой коллекции.

поэтому, чтобы ответить на ваш вопрос, почему ваш SelectedProject не настроен, я предлагаю вам проверить функциональность вашего сеттера на наличие ошибок. Хороший способ узнать, содержит ли привязка какие-либо ошибки, - проверить наши выходные данные на любую ошибку привязки сообщения во время отладки.

Примечание: Если ваш SelectedProject того же типа, что и элементы в ваших проектах CollectionViewSource, то вам не нужно бросать его перед использованием (Если вы не сделали SelectedProject типа объекта, то это также объясняет вашу проблему настройки).

EDIT: извините, короткий ответ нет, он не является избыточным. Наличие переменной, привязанной к текущему элементу, не является избыточным, если вы имеете в виду тестирование. Хорошим примером является то, когда вы хотите проверить старая версия SelectedItem с новым. Теперь, если вы только обратитесь к CollectionViewSource ' s SelectedItem, тогда может быть слишком поздно сравнивать, но с вашей собственной переменной вы можете проверить логику, прежде чем устанавливать ее снова.


в моем случае я пытался установить SelectedItem в ListBox, который ItemsSource был привязан к CollectionViewSource. Это грязно, потому что вам действительно нужно установить текущий элемент в CollectionViewSource, а не в ListBox.SelectedItem....поэтому я создал метод расширения для обработки этого сценария для меня:

YourListBox.SetCurrentItemOnView<YourObjectType>(item);

...и определение метода расширения

public static void SetCurrentItemOnView<T>(this System.Windows.Controls.ListBox listBox, T item) where T : YourObjectType
{
    var view = listBox.ItemsSource as ListCollectionView;
    if (view == null) { return; }

    var itemToSelect = (from p in view.SourceCollection.OfType<T>()
                        where p.ID == item.ID
                        select p).FirstOrDefault();

    view.MoveCurrentTo(itemToSelect);
}

Я предполагаю, что это была проблема для меня, потому что в моем случае элемент ссылка у меня была не такая, как ссылка на элемент, содержащаяся в ItemsSource, поэтому я должен был решить ее так.