如何在CollectionChanged上更新IValueConverter?

Bry*_*son 5 data-binding wpf inotifycollectionchanged

这是解释我的问题的基本示例.让我说我有

ObservableCollection<int> Numbers {get; set;}
Run Code Online (Sandbox Code Playgroud)

和一个返回Numbers之和的IValueConverter.

通常我要做的是将IValueConverter更改为IMultiValueConverter并将第二个值绑定到Numbers.Count,就像这样

<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
    <Binding Path="Numbers"     />
    <Binding Path="Numbers.Count"   />
</MultiBinding>
Run Code Online (Sandbox Code Playgroud)

但是我无法使用此方法来解决我的实际问题.似乎应该有一个更好的方法来更新绑定,当集合发生变化,我只是没想到.在将项目添加到Numbers并将其删除时,将值转换器运行的最佳方法是什么?

Bry*_*son 1

我最终做了类似的事情,似乎有效。它远非最佳解决方案,我仍然对更好的东西感兴趣,但它似乎适合我的目的。

class CollectionChangedHandlingValueConverter : IValueConverter
{
    DependencyObject myTarget;
    DependencyProperty myTargetProperty;

    //If this ever needs to be called from XAML you can make it a MarkupExtension and use ProvideValue to set up the Target and TargetProperty
    public CollectionChangedHandlingValueConverter(DependencyObject target, DependencyProperty dp)
    {
        myTarget = target;
        myTargetProperty = dp;
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        INotifyCollectionChanged collection = value as INotifyCollectionChanged;
        if (collection != null)
        {
            //It notifies of collection changed, try again when it changes
            collection.CollectionChanged += DataCollectionChanged;
        }

        //Do whatever conversions here
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion

    void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if ((myTarget != null) && (myTargetProperty != null))
        {
            BindingOperations.GetBindingExpressionBase(myTarget, myTargetProperty).UpdateTarget();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)