0

私は、MSDNや多くのチュートリアルで見られるように、コレクションビューソース(CVS)を実装しています。私の場合、Carクラスと、オブジェクトデータプロバイダー(ODP)を介してXAMLに表示されるCarsCollectionクラスがCVSにリンクされています。それはすべてうまくいきます。

並べ替えを追加し、最終的に、ユーザーが並べ替えるCarクラスのプロパティを選択できるようにする段階に到達しました。

次に、セカンダリソートを追加します。私の問題は、並べ替えを追加することではなく、削除することです。私の問題はこれです。私のコードでは、プライマリソートが最初に存在しない限り、セカンダリソートは発生しません(セカンダリ制御は無効になります)。たとえば、2次ソートを実行すると機能しますが、ソートする別のプロパティを選択しても何も起こりません。これは、3番目の並べ替えが追加されているためです。別のプロパティを選択しても、何も起こりません(4番目の並べ替えが追加されます)。

次のセカンダリソートを追加する前に、最後に適用されたセカンダリソートを削除できる構文がどこにも見つかりません。

一次ソート[0]と二次ソート[1]の2つの項目しかないことを考えると、次のようなコードを使用できるはずです。

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));
    }

基本的に、最初に前の2次ソートを削除し、次に新しいソートを追加して、コレクションビューソースに常に2つのソートのみが存在するようにするために必要なコードを探しています。次にこれを拡張して、3番目、4番目、またはその他のレベルの並べ替えを許可すると、リストには常にその数のアイテムしかありません。しかし、私が設定した方法のために、2番目のレベルが最初に存在しない限り、3番目のレベルは存在できません。したがって、ある種の取り違えはあり得ません。

これを実装する方法についてのアイデアはありがたいです。

4

1 に答える 1

1

アイテムを削除する方法が正しくありません。使用している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]);
于 2012-01-02T04:48:57.130 に答える