5

这是解释我的问题的基本示例。假设我有

ObservableCollection<int> Numbers {get; set;}

和一个返回数字总和的 IValueConverter。

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

<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
    <Binding Path="Numbers"     />
    <Binding Path="Numbers.Count"   />
</MultiBinding>

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

4

4 回答 4

2

这实际上非常困难。IValueConverter 不会更新,因此这不会像您希望的那样工作。

我在 Microsoft Expression Gallery 上编写了一个名为Collection Aggregator的示例,该示例显示了一种通过进行聚合的行为(计数,在您的情况下,尽管我也支持 Sum、Average 等)来实现这项工作的有效方法(如果复杂的话)你,而不是转换器。

于 2009-11-04T17:47:23.867 回答
2

在您的模型中,订阅 CollectionChanged 并引发 PropertyChanged:

Numbers.CollectionChanged += (o,e) => 
  OnPropertyChanged(new PropertyChangedEventArgs(nameof(Numbers)));

而且,正如 thomasgalliker 所提到的,当不再使用包含连接的模型时,您应该取消订阅该事件。

于 2017-11-09T22:27:25.137 回答
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();
        }
    }
}
于 2009-11-06T16:24:40.530 回答
1

我最终同步了集合(原始与转换器),例如看一下我帖子的底部:

http://alexburtsev.wordpress.com/2011/03/05/mvvm-pattern-in-silverlight-and-wpf/

于 2011-03-06T06:10:59.413 回答