问题
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.
回答1:
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.
private void SetSummary()
{
int initialCount = 0;
foreach(var item in _viewSource.View.SourceCollection)
{
initialCount++;
}
int filteredCount = 0;
foreach (var item in _viewSource.View)
{
filteredCount++;
}
}
回答2:
You could also do _viewSource.View.Cast<object>().Count()
for the filtered list and _viewSource.View.SourceCollection.Cast<object>().Count()
for the original.
回答3:
I think the better solution is, as usual, Linq!
_viewSource.View.Cast<[your_type]>().Count();
...or...
_viewSource.View.Cast<object>().Count();
...if you don't know the items' type at runtime!
回答4:
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 a ListCollectionViewSource
, which has a Count
property. It really depends on the properties of the data you're filtering.
回答5:
var count = DataGrid.ItemsSource.OfType<object>().Count();
回答6:
public static int Count(this ICollectionView view)
{
var index = 0;
foreach (var unused in view)
{
index++;
}
return index;
}
来源:https://stackoverflow.com/questions/3499903/how-to-get-items-count-from-collectionviewsource