В WPF можно фильтровать CollectionViewSource без кода?

На самом деле предмет говорит все.

 

Не то, чтобы у меня не было кода. Он просто дергает меня.

Вы можете сделать что угодно в XAML, если вы «достаточно стараетесь», вплоть до написания в нем целых программ .

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

        
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Markup; using System.Windows.Data; using System.Collections.ObjectModel; using System.Windows; using System.Text.RegularExpressions; namespace Test.MarkupExtensions { [ContentProperty("Filters")] class FilterExtension : MarkupExtension { private readonly Collection _filters = new Collection(); public ICollection Filters { get { return _filters; } } public override object ProvideValue(IServiceProvider serviceProvider) { return new FilterEventHandler((s, e) => { foreach (var filter in Filters) { var res = filter.Filter(e.Item); if (!res) { e.Accepted = false; return; } } e.Accepted = true; }); } } public interface IFilter { bool Filter(object item); } 
  // Sketchy Example Filter public class PropertyFilter : DependencyObject, IFilter { public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(string), typeof(PropertyFilter), new UIPropertyMetadata(null)); public string PropertyName { get { return (string)GetValue(PropertyNameProperty); } set { SetValue(PropertyNameProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(PropertyFilter), new UIPropertyMetadata(null)); public object Value { get { return (object)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static readonly DependencyProperty RegexPatternProperty = DependencyProperty.Register("RegexPattern", typeof(string), typeof(PropertyFilter), new UIPropertyMetadata(null)); public string RegexPattern { get { return (string)GetValue(RegexPatternProperty); } set { SetValue(RegexPatternProperty, value); } } public bool Filter(object item) { var type = item.GetType(); var itemValue = type.GetProperty(PropertyName).GetValue(item, null); if (RegexPattern == null) { return (object.Equals(itemValue, Value)); } else { if (itemValue is string == false) { throw new Exception("Cannot match non-string with regex."); } else { return Regex.Match((string)itemValue, RegexPattern).Success; } } } } } 

Расширения разметки – ваш друг, если вы хотите что-то сделать в XAML.

(Возможно, вы захотите указать имя расширения, то есть me:FilterExtension поскольку проверка «на лету» в Visual Studio может жаловаться без причины, она все еще компилируется и запускается, но предупреждения могут быть раздражающими.
Также не ожидайте, что CollectionViewSource.Filter появится в IntelliSense, он не ожидает, что вы установите этот обработчик через XML-элемент-нотацию)

На самом деле вам даже не нужен доступ к экземпляру CollectionViewSource , вы можете фильтровать исходную коллекцию непосредственно в ViewModel:

 ICollectionView view = CollectionViewSource.GetDefaultView(collection); view.Filter = predicate; 

(обратите внимание, что ICollectionView.Filter не является событием вроде CollectionViewSource.Filter , это свойство типа Predicate )

WPF автоматически создает тип CollectionView или производный тип, такой как ListCollectionView , BindingListCollectionView и т. Д. (Зависит от возможностей, обнаруженных в вашей исходной коллекции) – для любой привязки ItemsSource , если вы не поставляете его, когда вы связываете свой IEnumerable – напрямую к объекту ItemsControl.ItemsSource .

Этот автоматически созданный экземпляр CollectionView создается и поддерживается системой по принципу сбора данных (обратите внимание: не на контроль пользовательского интерфейса или на привязку). Другими словами, для каждого источника, к которому вы привязываетесь, будет отображаться ровно один глобальный общий «По умолчанию», и этот уникальный экземпляр CollectionView может быть извлечен (или создан по требованию) в любое время, передав IEnumerable статическому методу CollectionViewSource.GetDefaultView() .

Иногда даже если вы попытаетесь явно привязать свой собственный тип CollectionView -derived к элементу ItemsSource , механизм привязки данных WPF может обернуть его (используя внутренний тип CollectionViewProxy ).

В любом случае, каждый элемент ItemsControl с привязанным к данным свойством ItemsSource всегда будет иметь возможности сортировки и фильтрации, любезно предоставленные некоторыми элементами CollectionView . Вы можете легко выполнить фильтрацию / сортировку для любого данного IEnumerable , захватив и манипулируя своим «Default» CollectionView , но обратите внимание, что все привязанные к данным цели в пользовательском интерфейсе, которые в конечном итоге используют это представление, либо потому, что вы явно привязаны к CollectionViewSource.GetDefaultView() , или потому, что вы вообще не предоставили никакого представления – все они будут иметь одни и те же эффекты сортировки / фильтрации.

То, что не часто упоминается в этом вопросе, заключается в том, что в дополнение к привязке исходной коллекции к свойству ItemsSource элемента ItemsControl (как к цели привязки) вы также можете «одновременно» получить доступ к эффективной коллекции прикладных результатов фильтрации / сортировки – экземпляр CollectionView обработанный System.Windows.Controls.ItemCollection связанный с Items элемента управления (как источник привязки).

Это позволяет использовать многочисленные упрощенные сценарии XAML:

  1. Если для вашего приложения достаточно одного глобального фильтра / возможности сортировки для данного источника IEnumerable , просто привяжите его непосредственно к ItemsSource . Тем не менее, только в XAML вы можете фильтровать / сортировать элементы, обрабатывая свойство Items в том же ItemCollection управления, что и ItemCollection привязки ItemCollection . Он имеет много полезных связующих свойств для управления фильтром / сортировкой. Как отмечено, фильтрация / сортировка будет разделена между всеми элементами пользовательского интерфейса, которые таким образом связаны с одним и тем же источником IEnumerable . –или–

  2. Создайте и примените один или несколько отдельных (нестандартных) экземпляров CollectionView самостоятельно. Это позволяет каждому объекту, связанному с данными, иметь независимые настройки фильтра / сортировки. Это также можно сделать в XAML и / или вы можете создать свои собственные (List)CollectionView -удаленные classы. Этот тип подхода хорошо освещен в другом месте, но я хотел бы отметить здесь, что во многих случаях XAML можно упростить, используя тот же метод привязки данных к свойству ItemsControl.Items (как источник привязки) в чтобы получить доступ к эффективному CollectionView .

Резюме. Только с XAML вы можете привязать данные к коллекции, представляющей эффективные результаты любой текущей фильтрации / сортировки CollectionView в WPF ItemsControl , рассматривая ее свойство Items как источник привязки только для чтения. Это будет System.Windows.Controls.ItemCollection который предоставляет свойства bindable / mutable для управления активным фильтром и критериями сортировки.


[edit – дальнейшие мысли:]
Обратите внимание, что в простом случае привязки IEnumerable непосредственно к ItemsSource , ItemCollection , с ItemCollection вы можете привязываться в ItemsControl.Items будет оболочкой коллекции CollectionViewSource.GetDefaultView() исходной коллекции. Как обсуждалось выше, в использовании XAML нет необходимости связываться с этой оболочкой UI (через ItemsControl.Items ), в отличие от привязки к базовому представлению, которое оно обертывает (через CollectionViewSource.GetDefaultView ), поскольку прежний подход избавляет вас от неприятностей иначе упоминать CollectionView вообще.

Но, поскольку этот ItemCollection обертывает CollectionView по умолчанию, мне кажется, что даже в кодировке (где выбор менее очевиден), возможно, более целесообразно связываться с представлением, обнародованным пользовательским интерфейсом, поскольку такое, вероятно, лучше настроено к возможностям как источника данных, так и его цели управления пользовательским интерфейсом.

  • Как сделать элементы WPF ListView повторяющимися по горизонтали, например, горизонтальной полосой прокрутки?
  • Каков наилучший способ передать событие в ViewModel?
  • Как заставить детей StackPanel заполнить максимальное пространство вниз?
  • Как получить доступ к элементу управления внутри шаблона данных в пользовательском интерфейсе C # Metro в коде
  • WPF Binding - значение по умолчанию для пустой строки
  • Что означает «{Binding Path =.}» В привязке WPF?
  • Как заставить WPF использовать URI ресурсов, которые используют сильное имя сборки? Argh!
  • Можно ли выбрать текстовый блок WPF?
  • Как прокручивать в нижней части ScrollViewer автоматически с помощью Xaml и привязки?
  • Привязать к методу в WPF?
  • Лучший способ использовать векторное изображение в WPF?
  • Interesting Posts

    Экспоненциальная скользящая средняя, ​​отснятая в переменные времена

    Разница между java.lang.RuntimeException и java.lang.Exception

    Что такое serialVersionUID и почему я должен его использовать?

    Пользовательские правила в Outlook?

    Я хочу изменить DPI с помощью ImageMagick без изменения фактического размера байтов данных изображения

    Может ли jQuery добавлять запятые, когда пользователь вводит цифры?

    Разделение одной строки с несколькими столбцами на несколько строк

    Безопасно ли проверять значения с плавающей запятой на равенство 0?

    Неожиданное исключение поймало параметр «xxx» в «classе xxx: ошибка установки выражения« xxx »со значением

    Как отключить / включить диалоговые отрицательные положительные кнопки?

    Формат .NET DateTime «День» без начального нуля

    Как я могу извлечь букву диска для нового подключенного диска в байте?

    Как анализировать дамп памяти в Windows после синей ошибки экрана?

    Pacman открыть / закрыть анимацию

    Использование jQuery .live с событием toggle

    Давайте будем гением компьютера.