I am using CollectionViewSource to filter the records displayed in a ListBox. The xaml follows.
<Window x:Class="WPFStarter.ListBoxItemsFilter.ListBoxFilterUsingCollectionViewSource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="userControl"
Title="ListBoxFilterUsingCollectionViewSource" Height="300" Width="300">
<Window.Resources>
<CollectionViewSource Source="{Binding ElementName=userControl, Path=DataContext.Items}"
x:Key="cvs" Filter="CollectionViewSource_Filter"/>
</Window.Resources>
<StackPanel Orientation="Vertical">
<TextBox x:Name="txtSearch" TextChanged="txtSearch_TextChanged"/>
<TextBlock x:Name="txtSummary" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="8"></TextBlock>
<ListBox ItemsSource="{Binding Source={StaticResource cvs}}" DisplayMemberPath="First"/>
</StackPanel>
</Window>
And here is my code-behing ( please don;t mind this code-behind, in the real application i am using the best of MVVM for this scenario).
public partial class ListBoxFilterUsingCollectionViewSource : Window
{
private string _text="";
private readonly CollectionViewSource _viewSource;
public ListBoxFilterUsingCollectionViewSource()
{
InitializeComponent();
_viewSource = this.FindResource("cvs") as CollectionViewSource;
}
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
var character = e.Item as Character;
e.Accepted = character != null && character.First.ToLower().Contains(_text.ToLower());
}
private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
{
_text = txtSearch.Text;
_viewSource.View.Refresh();
SetSummary();
}
private void SetSummary()
{
var initialCount = 10; //HELP????
var filteredCount = 10; //HELP????
txtSummary.Text = String.Format("{0} of {1}", filteredCount, initialCount);
}
}
QUESTION: I Need help in writing the "SetSummary" method, wherein i can get the "initialCount" and the "filteredCount" from CollectionViewSource object.
Thanks for your interest.
I think the better solution is, as usual, Linq!
...or...
...if you don't know the items' type at runtime!
If you're doing MVVM, you could have your VM create a collection view rather than one being created on your behalf by the
CollectionViewSource
. Then, you have control over what type of CVS is created, so you can create aListCollectionViewSource
, which has aCount
property. It really depends on the properties of the data you're filtering.The source collection and collectionview both implements IEnumerable so you can always iterate over them and count how many are in them. But I would only recommend doing this if you have no access to the actual collection you used as source.
You could also do
_viewSource.View.Cast<object>().Count()
for the filtered list and_viewSource.View.SourceCollection.Cast<object>().Count()
for the original.