Can I filter a collection from xaml?
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 t开发者_JAVA百科o 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) ?
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;
}
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;
}
}
精彩评论