Как получить количество элементов из CollectionViewSource?

Я использую CollectionViewSource для фильтрации записей, отображаемых в ListBox. Далее следует 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>

И вот мой код (пожалуйста, не обращайте внимания на этот код, в реальном приложении я использую лучшее из 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.

Спасибо за ваш интерес.


person Manish Basantani    schedule 17.08.2010    source источник


Ответы (6)


Исходная коллекция и представление коллекции реализуют 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++;
    }
}
person Wallstreet Programmer    schedule 17.08.2010
comment
Просто обратите внимание, что filteredCount — это число видимых элементов, а не количество отфильтрованных элементов. - person apc; 13.02.2017

Вы также можете сделать _viewSource.View.Cast<object>().Count() для отфильтрованного списка и _viewSource.View.SourceCollection.Cast<object>().Count() для исходного.

person rhyek    schedule 05.01.2011
comment
Спасибо за пояснение, как получить отфильтрованное/отсортированное содержимое CollectionViewSource. Мне не удалось получить первый элемент в CollectionViewSource до вашего комментария: var firstItem = this.xViewInDescendingOrder.View.Cast‹Thing›().ElementAt‹Thing›(0); - person rfreytag; 27.05.2016

Я думаю, что лучшим решением, как обычно, является Linq!

_viewSource.View.Cast<[your_type]>().Count();

...or...

_viewSource.View.Cast<object>().Count();

... если вы не знаете тип элементов во время выполнения!

person MAXE    schedule 09.07.2012

Если вы используете MVVM, ваша виртуальная машина может создать представление коллекции, а не то, которое создается от вашего имени с помощью CollectionViewSource. Затем у вас есть контроль над тем, какой тип CVS создается, поэтому вы можете создать ListCollectionViewSource со свойством Count. Это действительно зависит от свойств данных, которые вы фильтруете.

person Kent Boogaart    schedule 17.08.2010
comment
Извините, я не мог получить его. Не могли бы вы объяснить с помощью кода, взяв мой код в контексте. Спасибо. - person Manish Basantani; 17.08.2010

person    schedule
comment
Благодаря этому вы можете получить подсчитанное количество элементов. Источник, например, 2, 3 - person EeNiArT; 12.12.2016
comment
Хотя этот код может ответить на вопрос, лучше объяснить, как решить проблему, и предоставить код в качестве примера или ссылки. Ответы, содержащие только код, могут сбивать с толку и не иметь контекста. - person Robert Columbia; 21.05.2018
comment
Спасибо г-ну Роберту Колумбии за то, что он помог мне помочь хорошими способами. - person EeNiArT; 29.06.2020

person    schedule
comment
Хотя этот код может ответить на вопрос, лучше объяснить, как решить проблему, и предоставить код в качестве примера или ссылки. Ответы, содержащие только код, могут сбивать с толку и не иметь контекста. - person Robert Columbia; 20.05.2018