0

MSDN 또는 많은 자습서에서 볼 수있는 것처럼 컬렉션보기 소스 (CVS)를 구현했습니다. 필자의 경우에는 Car 클래스와 Object Collection Provider (ODP)를 통해 XAML에 표시된 Cars Collection 클래스가있다. CVS는 이것에 링크되어있다. 그것은 모두 잘 작동합니다.CollectionViewSource에서 정렬 제거 C#

정렬을 추가 한 다음 결국 사용자가 정렬 할 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)); 
    } 

Esentially 내가 먼저 이전의 차 종류를 제거하는 데 필요한 코드를 찾고, 새로운 하나를 추가 : 다음

내 코드의 일부입니다 소스보기. 그런 다음 세 번째, 네 번째 또는 다른 정렬 수준을 허용하기 위해이 항목을 확장하면 항상 목록에있는 항목 수만 유지됩니다. 그러나 내가 설정 한 방식으로 인해 두 번째 레벨이 먼저 존재하지 않으면 세 번째 레벨 캔트가 존재합니다. 그래서 어떤 종류의 혼합이있을 수 없습니다.

구현 방법에 대한 아이디어가 있습니다.

답변

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은 의미가 없습니다. 그래서 당신이 sugested 어떻게 할 수 있습니다. 즉 자동차 제조 회사 속성에 1 차 정렬이 있습니다. Price 속성에 대한 보조 정렬입니다. remove 메서드를 사용하려면 SortDescription을 지정해야합니다. 그렇다면 제거 할 SortDescription의 ID를 어떻게 얻습니까? (이 경우에는 보조). 대답 해줘서 고마워. –

+1

@FrancisRodgers : 정확히 내가 응답 한 코드는 다음과 같습니다. 두 번째 정렬과 동일한 속성 이름을 가진 항목을 찾을 때까지 반복합니다. –

+0

죄송합니다. 나는 너무 빨리 대답했으며 코드를 보지 못했습니다. 죄송하며 귀하의 도움에 다시 한 번 감사드립니다. –