Удалить сортировку из CollectionViewSource C # - PullRequest
0 голосов
/ 02 января 2012

У меня реализован источник представления коллекций (CVS), как вы видите в MSDN или во многих руководствах.В моем случае класс Car и класс Cars Collection, который отображается в XAML через провайдера объектных данных (ODP). CVS связан с этим.Все это работает хорошо.

Я добавил сортировку, а затем, в конце концов, перешел на этап, на котором я мог позволить пользователю выбрать свойство класса Car для сортировки.

Далее я хочудобавить вторичную сортировку.Моя проблема не в добавлении сортировки, а в ее удалении.Моя проблема в этом.В моем коде нет вторичной сортировки и не происходит (вторичное управление отключено), если первичная сортировка не существует первой.Скажем так, теперь, если я делаю вторичную сортировку, она работает, но если я выберу другое свойство для сортировки, ничего не произойдет.Это связано с тем, что добавляется третий сорт, если я выбираю другое свойство, ничего не происходит (добавляется четвертый сорт и т. Д.).

Я не могу найти синтаксис в любом месте, что позволит мне удалить вторичную сортировку, примененную последнимперед добавлением следующей вторичной сортировки.

Учитывая, что всегда есть только два элемента - первичная сортировка [0] и вторичная сортировка [1], я должен иметь возможность использовать такой код:

lstCars.Items.SortDescriptions.RemoveAt(1);

но это не работает и даже очищает мои поля со списком элементов выбора (не мой фактический вопрос).

Я пытаюсь что-то вроде этого:

lstCars.Items.SortDescriptions.Remove(new SortDescription(cbxSortSecondary.SelectedItem.ToString(), direction));

Чтобы удалить фактический элемент изисточник, который я знаю, существует, потому что он был помещен туда, когда выбран из вторичного списка.Но хотя это должно работать, по какой-то причине это не так.

Ниже приводится часть моего кода:

    private void cbxSortPrimary_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //MessageBox.Show(((ComboBox)sender).Name);

        //Code to check if sorting is required or not, if so then do it.
        if(cbxSortPrimary.SelectedIndex == 0)//Sort Off
        {
            txtPrimary.Foreground = Brushes.Green;
            lstCars.Items.SortDescriptions.Clear();
            cbxSortSecondary.IsEnabled = false;
            chkSortSecAsc.IsEnabled = false;
        }
        else//Sort On
        {
            txtPrimary.Foreground = Brushes.Red;
            ApplyPrimarySort((bool)chkSortPriAsc.IsChecked);
            cbxSortSecondary.IsEnabled = true;
            chkSortSecAsc.IsEnabled = true;
        }
    }

    private void cbxSortSecondary_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //If there is no primary sort just exit the method.
        if(cbxSortPrimary.SelectedIndex == 0) return;

        if(cbxSortSecondary.SelectedIndex == 0)//Sort Off
        {
            txtSecondary.Foreground = Brushes.Green;
            RemoveSecondarySort((bool)chkSortSecAsc.IsChecked);
        }
        else//Sort On
        {
            txtSecondary.Foreground = Brushes.Red;
            ApplySecondarySort((bool)chkSortSecAsc.IsChecked);
        }
    }

    private void chkSortPriAsc_Checked(object sender, RoutedEventArgs e)
    {
        //Check to see if list is null, if so then exit (nothing to sort).
        if(lstCars == null) return;

        if(cbxSortPrimary.SelectedIndex > 0)
        {
            if(chkSortPriAsc.IsChecked == true) //Sort Ascending
            {
                chkSortPriAsc.Foreground = Brushes.Green;
                chkSortPriAsc.Content = "Asc";
                ApplyPrimarySort((bool)chkSortPriAsc.IsChecked);
            }
            else //Sort Decending
            {
                chkSortPriAsc.Foreground = Brushes.Red;
                chkSortPriAsc.Content = "Dec";
                ApplyPrimarySort((bool)chkSortPriAsc.IsChecked);
            }
        }
    }


    private void chkSortSecAsc_Checked(object sender, RoutedEventArgs e)
    {
        //Check to see if list is null, if so then exit (nothing to sort).
        if(lstCars == null) return;

        //If there is no primary sort just quit.
        if(cbxSortPrimary.SelectedIndex == 0) return;

        if(cbxSortSecondary.SelectedIndex > 0)
        {
            if(chkSortSecAsc.IsChecked == true) //Sort Ascending
            {
                chkSortSecAsc.Foreground = Brushes.Green;
                chkSortSecAsc.Content = "Asc";
                ApplySecondarySort((bool)chkSortPriAsc.IsChecked);
            }
            else //Sort Decending
            {
                chkSortSecAsc.Foreground = Brushes.Red;
                chkSortSecAsc.Content = "Dec";
                ApplySecondarySort((bool)chkSortPriAsc.IsChecked);
            }
        }
    }

    private void ApplyPrimarySort(bool asc)
    {
        ListSortDirection direction = new ListSortDirection();
        //Next determine if the direction of the sort is Ascending or Decending.
        if(asc)
            direction = ListSortDirection.Ascending;
        else
            direction = ListSortDirection.Descending;

        //Finally get the property to be sorted on and apply the sort, else remove any existing sorts.
        lstCars.Items.SortDescriptions.Clear();
        lstCars.Items.SortDescriptions.Add(new SortDescription(cbxSortPrimary.SelectedItem.ToString(), direction));

        //Then refresh the view.
        CollectionViewSource.GetDefaultView(lstCars.ItemsSource).Refresh();
    }

    private void ApplySecondarySort(bool asc)
    {
        ListSortDirection direction = new ListSortDirection();
        //Next determine if the direction of the sort is Ascending or Decending.
        if(asc)
            direction = ListSortDirection.Ascending;
        else
            direction = ListSortDirection.Descending;

        lstCars.Items.SortDescriptions.Remove(new SortDescription(cbxSortSecondary.SelectedItem.ToString(), direction));
        lstCars.Items.SortDescriptions.Add(new SortDescription(cbxSortSecondary.SelectedItem.ToString(), direction));

        //Then refresh the view.
        CollectionViewSource.GetDefaultView(lstCars.ItemsSource).Refresh();
    }


    private void RemoveSecondarySort(bool asc)
    {
        ListSortDirection direction = new ListSortDirection();
        //Next determine if the direction of the sort is Ascending or Decending.
        if(asc)
            direction = ListSortDirection.Ascending;
        else
            direction = ListSortDirection.Descending;

        lstCars.Items.SortDescriptions.Remove(new SortDescription(cbxSortSecondary.SelectedItem.ToString(), direction));
    }

По сути, я ищу код, который мне нужен, чтобы сначала удалить предыдущийвторичная сортировка, затем добавьте новую, чтобы в источнике представления коллекции всегда было только две сортировки.Если бы мне пришлось расширить это, чтобы разрешить третий, четвертый или любой другой уровень сортировки, в списке всегда будет только это количество элементов.Однако из-за того, как я его настроил, 3-й уровень не может существовать, если только второй уровень не существует первым.Так что не может быть никаких путаниц.

Любые идеи о том, как реализовать это, будут оценены.

1 Ответ

1 голос
/ 02 января 2012

Неверный способ удаления элементов: используемый вами метод Remove удаляет указанный объект из коллекции (в частности, первый экземпляр указанного объекта), но так как вы передаетеновый объект, он не будет в коллекции и, следовательно, не будет удален.

Лучше всего циклически просмотреть коллекцию и посмотреть, какой элемент соответствует вашим критериям для удаления, и удалить этот элемент.

Например:

        var sortDescriptions = lstCars.Items.SortDescriptions;

        for (int nI = sortDescriptions.Count; nI >= 0; nI--)
        {
            if (sortDescriptions[nI].PropertyName == cbxSortSecondary.SelectedItem.ToString())
            {
                sortDescriptions.RemoveAt(nI);
            }
        }

Обновление

Альтернатива этой строке:

                sortDescriptions.RemoveAt(nI);

- использовать эту строку, но они должны быть функционально эквивалентны:

                sortDescriptions.Remove(sortDescriptions[nI]);
...