这是解释我的问题的基本示例。假设我有
ObservableCollection<int> Numbers {get; set;}
和一个返回Numbers之和的IValueConverter。
通常我要做的是将IValueConverter更改为IMultiValueConverter并将第二个值绑定到Numbers.Count,如下所示
<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
<Binding Path="Numbers" />
<Binding Path="Numbers.Count" />
</MultiBinding>
但是我无法使用此方法来解决我的实际问题。似乎应该有一个更好的方法来更新绑定,当集合发生变化,我只是没想到。在将项目添加到Numbers并将其删除时,将值转换器运行的最佳方法是什么?
答案 0 :(得分:3)
我最终做了类似这样的事情似乎有效。它远非一个最佳的解决方案,我仍然对更好的东西感兴趣,但它似乎适合我的目的。
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();
}
}
}
答案 1 :(得分:2)
这实际上非常困难。 IValueConverter不会更新,因此这不会像您希望的那样工作。
我在Microsoft Expression Gallery上编写了一个名为Collection Aggregator的示例,该示例显示了一种有效的方法,通过执行聚合的行为来实现此功能(在您的情况下,Count,尽管我也支持Sum) ,平均值等),而不是转换器。
答案 2 :(得分:1)
我最终同步收集(原始与转换器),看看我的帖子的buttom例如:
http://alexburtsev.wordpress.com/2011/03/05/mvvm-pattern-in-silverlight-and-wpf/
答案 3 :(得分:1)
在您的模型中,订阅CollectionChanged并引发PropertyChanged:
Numbers.CollectionChanged += (o,e) =>
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Numbers)));