2012-05-05 5 views
2

XAML의 내 뷰 모델에 필터 조건부 속성을 제공 할 수 있도록 CollectionViewSource에 연결된 동작을 추가하려고합니다.연결된 동작을 CollectionViewSource에 어떻게 추가 할 수 있습니까?

XAML은 다음과 같습니다 :

<DataGrid ItemsSource="{Binding}"> 
    <DataGrid.DataContext> 
     <CollectionViewSource Source="{Binding Path=Items}" 
       acb:CollectionViewSourceItemFilter.ItemFilter="{Binding Path=ItemFilter}" /> 
    </DataGrid.DataContext> 
</DataGrid> 

을 그러나, 나는 오류가 점점 오전 :

A 'Binding' cannot be set on the 'SetItemFilter' property of type 
'CollectionViewSource'. A 'Binding' can only be set on a DependencyProperty of a 
DependencyObject. 

CollectionViewSource은 DependencyObject에 나타납니다. 내가 뭘 잘못하고 있는지 모르겠다.

다음은 행동 코드 :

public static class CollectionViewSourceItemFilter 
{ 
    /// <summary> 
    /// Gets the property value. 
    /// </summary> 
    public static Predicate<object> GetItemFilter(CollectionViewSource collectionViewSource) 
    { 
     return (Predicate<object>)collectionViewSource.GetValue(ItemFilter); 
    } 

    /// <summary> 
    /// Sets the property value. 
    /// </summary> 
    public static void SetItemFilter(CollectionViewSource collectionViewSource, Predicate<object> value) 
    { 
     collectionViewSource.SetValue(ItemFilter, value); 
    } 

    /// <summary> 
    /// The ItemFilter dependency property. 
    /// </summary> 
    public static readonly DependencyProperty ItemFilter = 
     DependencyProperty.RegisterAttached(
     "ItemFilter", 
     typeof(Predicate<object>), 
     typeof(ItemFilterBehavior), 
     new UIPropertyMetadata(null, OnItemFilterChanged)); 

    private static void OnItemFilterChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     CollectionViewSource collectionViewSource = depObj as CollectionViewSource; 
     if (collectionViewSource == null) 
      return; 

     if (!Equals(e.NewValue, e.OldValue)) 
     { 
      var newFilter = (Predicate<object>)e.NewValue; 

      // Remove any previous filter. 
      ItemFilterBehavior oldBehavior; 
      if (behaviors.TryGetValue(collectionViewSource, out oldBehavior)) 
      { 
       oldBehavior.Unregister(); 
       behaviors.Remove(collectionViewSource); 
      } 

      if (newFilter != null) 
       behaviors.Add(collectionViewSource, new ItemFilterBehavior(collectionViewSource, newFilter)); 
     } 
    } 

    private class ItemFilterBehavior 
    { 
     public ItemFilterBehavior(CollectionViewSource collectionViewSource, Predicate<object> filter) 
     { 
      _collectionViewSource = collectionViewSource; 
      _filter = filter; 
      _collectionViewSource.Filter += collectionViewSource_Filter; 
     } 

     void collectionViewSource_Filter(object sender, FilterEventArgs e) 
     { 
      e.Accepted = _filter(e.Item); 
     } 

     public void Unregister() 
     { 
      _collectionViewSource.Filter -= collectionViewSource_Filter; 
     } 

     private readonly CollectionViewSource _collectionViewSource; 
     private readonly Predicate<object> _filter; 
    } 

    private static readonly IDictionary<CollectionViewSource, ItemFilterBehavior> behaviors = new ConcurrentDictionary<CollectionViewSource, ItemFilterBehavior>(); 
} 
+0

다음을 시도해보십시오.'public static readonly DependencyProperty ItemFilterProperty = ...' –

+1

질문을 올리신 것을 감사합니다. 그것은 저와 똑같은 일을하려고하는 누군가가 있다는 것을 깨닫게했습니다. – jpierson

+0

@jpierson 게시 날짜 기념일 upvote. MVVM에서 CollectionViewSource 필터링에 대한 모든 토론을 통해이 게시물에 많은 관심을 기울일 것이라고 생각할 수 있습니다. – TaterJuice

답변

1

질문의 동작 코드를 게시를 알아 내기 위해 나를했다. My DependencyProperty는 소유자 유형으로 CollectionViewSourceItemFilter 대신 ItemFilterBehavior를 사용했습니다.

관련 문제