Как получить количество элементов из CollectionViewSource?
Я использую CollectionViewSource для фильтрации записей, отображаемых в списке. Далее следует xaml.
<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>
и вот мой код-behing (пожалуйста, не обращайте внимания на этот код, в реальном приложении я использую лучшее из MVVM для этого сценария).
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);
}
}
вопрос: Мне нужна помощь в написании метода "SetSummary", в котором я могу получить" initialCount "и" filteredCount " из объекта CollectionViewSource.
спасибо ваш интерес.
6 ответов
исходная коллекция и collectionview реализуют IEnumerable, поэтому вы всегда можете перебирать их и подсчитывать, сколько их в них. Но я бы рекомендовал сделать это, только если у вас нет доступа к фактической коллекции, которую вы использовали в качестве источника.
private void SetSummary()
{
int initialCount = 0;
foreach(var item in _viewSource.View.SourceCollection)
{
initialCount++;
}
int filteredCount = 0;
foreach (var item in _viewSource.View)
{
filteredCount++;
}
}
вы также можете сделать _viewSource.View.Cast<object>().Count() для отфильтрованного списка и _viewSource.View.SourceCollection.Cast<object>().Count() для оригинала.
Я думаю, что лучшее решение, как обычно, Linq!
_viewSource.View.Cast<[your_type]>().Count();
...или...
_viewSource.View.Cast<object>().Count();
...если вы не знаете тип элементов во время выполнения!
Если вы делаете MVVM, у вас может быть VM создать представление коллекции, а не один, созданный от вашего имени CollectionViewSource. Затем у вас есть контроль над тем, какой тип CVS создается, поэтому вы можете создать ListCollectionViewSource, которая имеет Count собственность. Это действительно зависит от свойств данных фильтрации.
public static int Count(this ICollectionView view)
{
var index = 0;
foreach (var unused in view)
{
index++;
}
return index;
}