Фильтры Silverlight 4 CollectionViewSource ListBox на основе типа данных

У меня есть ListBox, который я загружаю объектами трех типов, которые наследуются от одного и того же родительского типа. Я хотел бы отфильтровать объекты в ListBox на основе их типа с помощью CollectionViewSource, но у меня возникли проблемы с написанием фильтров.

Мой XAML выглядит следующим образом:

<UserControl.Resources>
    <CollectionViewSource x:Key="eventsViewSource" 
                          Source="{Binding lifeCycleEvents}" >
        <CollectionViewSource.SortDescriptions>
            <compMod:SortDescription PropertyName="Date" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</UserControl.Resources>


<ListBox Name="lstEventHistory"  ItemsSource="{Binding Source={StaticResource eventsViewSource}}">
...
</ListBox>

В коде программной части я загружаю наблюдаемую коллекцию объектов, возвращаемых вызовом асинхронного метода:

private ObservableCollection<LifeCycleEvent> lifeCycleEvents;

...
                lifeCycleEvents= e.Result; 
                CollectionViewSource eventsViewSource = this.Resources["eventsViewSource"] as CollectionViewSource;
                eventsViewSource.Source = lifeCycleEvents;

Теперь я хотел бы написать фильтр, который будет отображать только объекты определенного типа на основе флажков, которые пользователь будет щелкать в пользовательском интерфейсе.

Ниже приведена неудачная попытка написать один фильтр:

eventsViewSource.Filter = new Predicate<object>(rmaFilter);

public bool rmaFilter(object item)
     {
        if(item.GetType() == typeof(RmaEvent))
            return true;
        else 
            return false;
     }

Это дает следующую ошибку: «Событие System.Windows.Data.CollectionViewSrouce.Filter может отображаться только слева от += или -=".

Я не смог найти ни одного учебника, который делает именно то, что мне нужно. Те, которые существуют, зависят от представления по умолчанию, которого нет в Silverlight. Один из таких уроков, который я просмотрел, можно найти здесь

Любые советы приветствуются!


person Bruno    schedule 11.04.2013    source источник


Ответы (2)


Свойство Filter для CollectionView и CollectionViewSource является событием и содержит коллекцию типа FilterEventHandler, а не Predicate. Каждый обработчик событий вызывается для каждого элемента в CollectionView, чтобы определить, следует ли отображать его или нет.

Кроме того, добавление или удаление обработчиков событий из свойства Filter приведет к вызову обработчиков событий и обновлению коллекции.

Таким образом, правильный код для подключения обработчиков событий Filter:

eventsViewSource.Filter += new FilterEventHandler(rmaFilter);

И чтобы удалить его:

eventsViewSource.Filter -= new FilterEventHandler(rmaFilter);

И новый обработчик:

public void rmaFilter(object sender, FilterEventArgs args)
 {
    args.Accepted = args.Item is RmaType;
 }
person jnosek    schedule 12.04.2013

Согласно документации MSDN, фильтр событие типа CollectionViewSource. Так? правильный синтаксис:

eventsViewSource.Filter += new Predicate<object>(rmaFilter);

В руководстве по ссылке выше автор использовал статический метод типа CollectionViewSource, возвращающий объект CollectionView. Этот объект CollectionView имеет свойство Filter (еще не событие!), и вы можете назначить ему делегата Filter, используя синтаксис =

person Dzmitry Martavoi    schedule 11.04.2013