我有一个 Collection View Source (CVS) 实现,就像你在 MSDN 或许多教程中看到的那样。在我的例子中,一个 Car 类和一个通过 Object Data Provider (ODP) 在 XAML 中显示的 Cars Collection 类 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));
}
基本上我正在寻找我需要首先删除以前的二级排序,然后添加一个新的代码,因此集合视图源中总是只有两种排序。如果我要扩展它以允许第三、第四或任何其他级别的排序,那么列表中总是只有那个数量的项目。但是,由于我设置它的方式,除非首先存在第二级,否则第三级不能存在。所以不能混为一谈。
任何关于如何实现这一点的想法都会受到赞赏。