2013-07-10 2 views
2

tldr : CollectionViewSource.Filter는 다른 컨트롤로 덮어 씁니다. 컨트롤에서 미리 필터링 된 컬렉션 만 볼 수 있도록 두 단계의 필터링을 수행하려면 어떻게해야합니까?CollectionViewSources를 중첩 할 수 있습니까?

ICollectionView를 통해 내 viewmodel의 컬렉션에 바인딩하는 제 3 자 그리드 컨트롤이 있습니다.

private CollectionViewSource _filteredCollection; 

public ItemListViewModel (List<ItemViewModel> items) 
{ 
    _items = items; 
    _filteredCollection = new CollectionViewSource {Source = _items}; 
} 

public ICollectionView AllInstructions 
{ 
    get { return _filteredCollection.View; } 
} 

잘 작동하고 gridcontrol이 자체 필터링, 그룹화 및 정렬을 수행 할 수 있습니다. 는 지금은 예상대로

public ItemListViewModel (List<ItemViewModel> items) 
{ 
    ... 
    _filteredCollection.Filter += new FilterEventHandler(FilterByDate); 
} 

private void FilterByDate(object sender, FilterEventArgs e) 
{ 
    var item = e.Item as ItemViewModel; 

    if (item == null) 
    { 
     e.Accepted = false; 
    } 
    else 
    { 
     e.Accepted = item.CreatedDate >= _selectedDate; 
    } 
} 

나의 새로운 필터가 작동 (오늘의 항목을 표시, 즉 버튼)을 격자의 한 전에 내 자신의 필터를 적용 할. 문제는 gridcontrol이 제대로 작동하지 않고 자체 필터를 덮어 쓰는 것입니다.

필자가 생각한 것은 _filteredCollection CVS에서 필터링을 수행 한 다음 gridcontrol에 전달하는 다른 CollectionViewSource 또는 CollectionView를 만드는 것이 었습니다.

ICollectionView에서 _filteredCollection을 래핑하면 필터링의 두 계층이 완벽하게 작동하지만 ICollectionView의 기본 생성자에 CanSort 및 CanGroup이 false로 설정되어 있기 때문에 정렬하거나 그룹화 할 수 없습니다.

내가 알 수없는 것은 _filteredCollection을 두 번째 CollectionViewSource의 생성자에 공급하는 방법입니다. 가능합니까 아니면 잘못된 각도에서이 문제에 접근하고 있습니까?

답변

2

다음 코드에서와 같이, ListCollectionView에서 파생에 의해 미리 정의 된 필터를 사용하여 자신의 콜렉션 뷰를 만들 수 있습니다 이 컨트롤을 모든 컨트롤과 함께 테스트했지만 작동해야한다고 생각합니다.

2

내가 올바르게 이해하면 여러 필터를 목록에 적용하고 싶지 않습니까?

몇 가지 술어를 관리하는 기본 FilterHandler에 대한 필터. 좀 더 유연하게 만들기 위해서, 당신은 메인 FilterHandler가 unstack 할리스트 나 스택에이 술어를 추가 할 수 있습니다. CollectionViewSources의 새로 고침 프로세스로 인해 다음 Refresh()에서 새 필터가 고려됩니다.

지금
class FilteredListCollectionView : ListCollectionView 
{ 
    // internal filter 
    private Predicate<object> preFilter; 

    // public filter 
    private Predicate<object> filter; 

    public FilteredListCollectionView(IList list) 
     : base(list) 
    { 
    } 

    private Predicate<object> GetCombinedFilter() 
    { 
     if (this.preFilter != null) 
      return this.filter != null ? x => this.preFilter(x) && this.filter(x) : this.preFilter; 
     else 
      return this.filter; 
    } 

    public Predicate<object> PreFilter 
    { 
     get { return this.preFilter; } 
     set 
     { 
      this.preFilter = value; 
      base.Filter = this.GetCombinedFilter(); 
     } 
    } 

    public override Predicate<object> Filter 
    { 
     get { return base.Filter; } 
     set 
     { 
      this.filter = value; 
      base.Filter = this.GetCombinedFilter(); 
     } 
    } 
} 

이처럼 사용할 수 있습니다 :

private FilteredListCollectionView _filteredCollection; 

public ItemListViewModel(List<ItemViewModel> items) 
{ 
    _items = items; 
    _filteredCollection = new FilteredListCollectionView(_items); 
    _filteredCollection.PreFilter = FilterByDate; 
} 

public ICollectionView AllInstructions 
{ 
    get { return _filteredCollection; } 
} 

private bool FilterByDate(object obj) 
{ 
    var item = obj as ItemViewModel; 

    if (item == null) 
    { 
     return false; 
    } 
    else 
    { 
     return item.CreatedDate >= _selectedDate; 
    } 
} 

I 피난처 '

관련 문제