Can I filter a collection from xaml?

强颜欢笑 提交于 2019-12-30 04:35:35

问题


I have a wpf-mvvm application.

I have an observable collection in my viewmodel

public ObservableCollection<BatchImportResultMessageDto> ImportMessageList { get; set; } 

"BatchImportResultMessageDto" contains two properties..

result type..and message. Result type can be success or failure.

I need to display success in one list box ..and failure in another listbox.

I can do this..by having 2 observable collections in viewmodel to hold success/failure.

public ObservableCollection<BatchImportResultMessageDto> ImportFailureMessageList { get; set; } // To hold the failure messages.
public ObservableCollection<BatchImportResultMessageDto> ImportSuccessMessageList { get; set; } // To hold the sucess messages.

But is there any other better way so that i can filter it (without new two collections) ?


回答1:


You can use a CollectionViewSource and make it a property of your view model, and bind to that instead of your ImportMessageList collection directly from the XAML. Set your ImportMessageList collection as the Source of the CollectionViewSource, and then configure a predicate to do your filtering on the CollectionViewSource.

Something like:

private ICollectionView messageListView;
public ICollectionView MessageListView
{
    get { return this.messageListView; }
    private set
    {
      if (value == this.messageListView)
      {
        return;
      }

      this.messageListView = value;
      this.NotifyOfPropertyChange(() => this.MessageListView);
    }
}

...


this.MessageListView = CollectionViewSource.GetDefaultView(this.ImportMessageList);
this.MessageListView.Filter = new Predicate<object>(this.FilterMessageList);

...

public bool FilterMessageList(object item)
{
  // inspect item as message here, and return true 
  // for that object instance to include it, false otherwise
  return true;
}



回答2:


You can do this by creating two CollectionViewSource objects and setting a filter on each.

How to create a CVS in xaml from a VM binding (Source):

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <CollectionViewSource Source="{Binding}" x:Key="customerView">
           <CollectionViewSource.GroupDescriptions>
               <PropertyGroupDescription PropertyName="Country" />
           </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <ListBox ItemSource="{Binding Source={StaticResource customerView}}" />
</Window>

How to filter a CVS in a code behind (You can use reflection to look at the properties of your model if you don't want to make a reference to it. Source):

<CollectionViewSource x:Key="MyCVS"
                              Source="{StaticResource CulturesProvider}"
                              Filter="MyCVS_Filter" />

with (code behind)

void MyCVS_Filter(object sender, FilterEventArgs e)
{
    CultureInfo item = e.Item as CultureInfo;
    if (item.IetfLanguageTag.StartsWith("en-"))
    {
        e.Accepted = true;
    }
    else
    {
        e.Accepted = false;
    }
}


来源:https://stackoverflow.com/questions/4923935/can-i-filter-a-collection-from-xaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!