Как я могу связать и отсортировать коллекцию

#wpf #data-binding

#wpf #привязка данных

Вопрос:

Если у меня есть несортированная коллекция, есть ли простой способ связать и отсортировать ее. Я хотел бы сделать это в XAML (без Linq, без C #)

Если мой DataContext имеет свойство, скажем, myItems, его легко привязать к нему:

 <ListBox ItemsSource={Binding MyItems}/>
  

Тем не менее, я бы хотел также отсортировать ее. Решением должно быть использование CollectionViewSource, но у меня это не работает:

 <ListBox>
 <ListBox.ItemsSource>
  <Binding>
   <Binding.Source>
    <CollectionViewSource Source={Binding MyItems}/>
   </Binding.Source>
  </Binding>
 </ListBox.ItemsSource>
</ListBox>
  

На этом этапе мой ListBox теряет свои элементы.
Я упускаю что-то очевидное?

Ответ №1:

Вы можете определить CollectionViewSource как ресурс и обеспечить желаемую сортировку…

 <Window.Resources>
    <CollectionViewSource x:Key="cvs" Source="{Binding MyItems}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="MyItemName" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</Window.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Source={StaticResource cvs}}"/>
</Grid>
  

scm Пространство имен является xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"

Комментарии:

1. Спасибо за предложение. Однако мой listbox находится в DataTemplate, поэтому я не могу использовать ресурс. Почему он работает как ресурс, а не как источник привязки?

2. Ах, в вашем первоначальном ответе не было SortDescriptions , поэтому я ответил с ним, и вы отредактировали, чтобы включить

Ответ №2:

Создайте CollectionViewSource в CodeBehind, который считывается из myItems, и привяжите к нему свой ListBox

 <ListBox ItemsSource="{Binding MyCollectionViewSource"} />
  

Комментарии:

1. В -1 OP конкретно указано, что они хотят избежать C # (код позади)

2. Не заслуживает значения -1. Конечно, в OP это сказано, но будущие пользователи, ищущие ответы на этот вопрос, могут посчитать вклад @Rachel ценным.

3. @Robaticus Все становятся не в форме при значении -1. Поскольку в OP явно указано, что C # не должен использоваться; линия должна быть где-то нарисована. Если OP явно не вызывал нежелание использовать C #, ответ был бы прекрасным. Попытка сохранить ответы относительно вопроса — это все.

4. @Aaron Я предположил, что OP не хочет никакого дополнительного кода для выполнения сортировки, такого как код за представлением или конвертер. Я все еще думаю, что лучше изменить источник ваших данных, чтобы он указывал на CollectionViewSource , а не непосредственно на список, если вы собираетесь его сортировать. При желании позже это также позволило бы использовать другие параметры сортировки.

5. Я полностью согласен. Я возвращаю CollectionViewSource из моей ViewModel точно так, как вы рекомендовали. Явно укажите тот факт, что вы отметили ссылку OP на C # при редактировании, и я могу удалить значение -1. Опять же, это не говорит о том, что вы ошибаетесь… просто немного не по теме.

Ответ №3:

Ни один из других ответов фактически не касается сортировки. Они оба правы насчет CollectionViewSource , но вы можете использовать это для выполнения сортировки с помощью CollectionViewSource.SortDescription . Взято из здесь и изменено:

 <Window.Resources>

   <src:MyItems x:Key="MyItems"/>

   <CollectionViewSource Source="{StaticResource MyItems}" x:Key="cvs">
     <CollectionViewSource.SortDescriptions>
       <scm:SortDescription PropertyName="CityName"/>
     </CollectionViewSource.SortDescriptions>
   </CollectionViewSource>
</Window.Resources>

<ListBox ItemsSource="{Binding Source={StaticResource cvs}}"
     DisplayMemberPath="CityName" Name="lb">
  <ListBox.GroupStyle>
    <x:Static Member="GroupStyle.Default"/>
  </ListBox.GroupStyle>
</ListBox>
  

В этом примере CityName это будет свойство каждого элемента в MyItems , используемое для выполнения сортировки

Комментарии:

1. ummm…my в ответе говорится о SortDescriptions.

2. @Aaron — этого не произошло, когда я впервые загрузил страницу. Вы отредактировали, чтобы включить. Конечно, правки в течение первых нескольких минут публикации не отображаются как правки, поэтому я не могу это доказать.