ICollectionView Проблема сортировки в ListView - PullRequest
0 голосов
/ 24 августа 2010

Я видел, как ICollectionView вводится с WPF для обработки ситуаций, когда вам нужно включить сортировку и фильтрацию.Я даже видел несколько статей, которые сортируют предметы, но моя главная проблема в том, почему мой подход терпит неудачу.Давайте посмотрим мой код:

 <ListView ItemsSource="{Binding}" x:Name="lvItems" GridViewColumnHeader.Click="ListView_Click">
            <ListView.View>
                <GridView AllowsColumnReorder="True">
                    <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}" />
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                    <GridViewColumn Header="Developer">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=Developer}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Salary">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=Salary}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                </GridView>
            </ListView.View>
        </ListView>

В codebehind, когда элемент нажимается, я делаю так:

  ICollectionView Source { get; set; }


        private void ListView_Click(object sender, RoutedEventArgs e)
        {
            GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
            if(currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
            {
                //using (this.Source.DeferRefresh())
                //{
                    SortDescription currentPropertySort = this.Source.SortDescriptions.FirstOrDefault<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));
                    if (currentPropertySort != null)
                    {
                        if (currentPropertySort.Direction == ListSortDirection.Ascending)
                            currentPropertySort.Direction = ListSortDirection.Descending;
                        else
                            currentPropertySort.Direction = ListSortDirection.Ascending;

                    }
                    else
                        this.Source.SortDescriptions.Add(new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));


                //}
                    this.Source.Refresh();
                    this.lvItems.DataContext = this.Source;
                    this.lvItems.UpdateLayout();
            }


        }

Так что всякий раз, когда нажимается заголовок для ListBox,пункт должен быть отсортирован.Я держу коллекцию, используя свойство с именем Source, а затем использую его, вызывая lvItems.DataContext = this.Source. Но код, похоже, не работает.

1 Ответ

3 голосов
/ 24 августа 2010

Вот обновленная версия вашего метода ListView_Click, который несколько работает.Я не уверен, какое именно поведение сортировки вы искали, но приведенная ниже версия «складывает» набор описаний сортировки, делая последний нажатый столбец «основным описанием сортировки».Я надеюсь, что это имеет смысл, и я надеюсь, что приведенный ниже код поможет.=)

private void ListView_Click(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader currentHeader = e.OriginalSource as GridViewColumnHeader;
    if(currentHeader != null && currentHeader.Role != GridViewColumnHeaderRole.Padding)
    {
        if (this.Source.SortDescriptions
            .Count((item) => item.PropertyName.Equals(currentHeader.Column.Header.ToString())) > 0)                
        {
            SortDescription currentPropertySort = this.Source
                .SortDescriptions
                .First<SortDescription>(item => item.PropertyName.Equals(currentHeader.Column.Header.ToString()));

            //Toggle sort direction.
            ListSortDirection direction = 
                (currentPropertySort.Direction == ListSortDirection.Ascending)?
                ListSortDirection.Descending : ListSortDirection.Ascending;

            //Remove existing sort
            this.Source.SortDescriptions.Remove(currentPropertySort);
            this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), direction));
        }
        else
        {
            this.Source.SortDescriptions.Insert(0, new SortDescription(currentHeader.Column.Header.ToString(), ListSortDirection.Ascending));
        }

        this.Source.Refresh();
    }
}

РЕДАКТИРОВАТЬ:

Кстати, одной из проблем в вашем коде выше является ваш вызов «FirstOrDefault» для запроса существующего SortDescription.Видите, SortDescription - это структура, которая не имеет значения NULL, поэтому вызов FirstOrDefault никогда не будет нулевым и всегда будет возвращать экземпляр.Следовательно, «оператор else» в вашем коде выше никогда не будет вызван.

...