2
我想添加一個附加的行爲到一個CollectionViewSource,以便我可以在我的視圖模型在XAML中提供一個過濾器謂詞屬性。如何將附加的行爲添加到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>();
}
試試這個:'public static readonly DependencyProperty ItemFilterProperty = ...' –
感謝您發佈您的問題。這讓我意識到,有人在那裏試圖做同樣的事情,我是。 – jpierson
@jpierson後日期週年upvote。所有關於在MVVM中過濾CollectionViewSource的討論,你都會認爲這篇文章會有更多的關注。 – TaterJuice