2012-01-02 26 views
0

排序我有一個集合查看源代碼(CVS)實現就像你在MSDN或很多教程看到的。在我的情況下,Car類和Cars Collection類是通過對象數據提供程序(ODP)在XAML中顯示的。CVS與此鏈接。這一切運作良好。取下CollectionViewSource C#

我添加了一個排序,那麼最終它到了一個階段,我可以允許用戶選擇汽車類的屬性進行排序。

接下來我想補充一個次要排序。我的問題不是添加排序,而是刪除它。我的問題是這樣的。在我的代碼中,除非首先存在主要排序,否則不會進行二級排序併發生(輔助控制被禁用)。讓我們說,它現在如果我做第二次排序,它的工作原理,但如果我選擇另一個屬性排序,沒有任何反應。這是因爲添加了第三種類型,如果我選擇另一個屬性,則什麼都不會發生(第四種添加等等)。

我無法找到任何地方的語法,讓我去掉最後應用的輔助排序,添加下一個次要排序前。

鑑於有永遠只能兩個項目 - 主要排序[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)); 
    } 

Esentially我要尋找我需要先刪除以前的輔助排序的代碼,然後添加一個新的所以總是隻有兩類集合中查看源代碼。如果我要擴大這個範圍以允許第三個,第四個或任何其他級別的排序,那麼總是隻有該列表中的項目數量。然而,由於我設置的方式,除非第一個級別存在,否則存在第3級存在。所以不能混淆不清。

就如何落實這一任何想法將appreicated。

回答

1

刪除項目的方式不正確:您正在使用的Remove method會從集合中刪除指定的對象(特別是指定對象的第一個實例),但由於您傳遞的是新對象,因此它會贏得不在集合中,因此不會被刪除。

最好的辦法是通過收集週期,看看哪些項目符合您的標準去除,並刪除該項目。

例如:

 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]); 
+0

這就是我的想法。一個新的SortDescription沒有意義。所以,我怎麼能當你吞下去。即我有一個關於汽車製造商財產的主要排序。 Price屬性的次要排序。 remove方法要求我給它一個SortDescription。那麼,如何獲得我想要移除的SortDescription的標識。 (在這種情況下是次要的)。謝謝回答。 – 2012-01-02 04:59:45

+1

@FrancisRodgers:這正是我回答的代碼所做的:循環直到它找到具有與次要排序相同屬性名稱的項目。 – 2012-01-02 05:22:30

+0

對不起,我回答太快,沒有看到你的代碼。道歉,並再次感謝您的幫助。 – 2012-01-02 05:56:20