【发布时间】:2015-02-12 20:48:32
【问题描述】:
我有一个DataGrid 绑定到一个ObservableCollection<Client>。
我有一个UserControl,它负责从Textbox 值对集合应用过滤器,如下所示:
private void UCFilterBox_SearchTextChanged(object sender, string e)
{
var coll = CollectionViewSource.GetDefaultView(dgClients.ItemsSource);
coll.Filter = o =>
{
var c = o as Client;
if (c != null)
{
bool ret = (the filter...)
return ret;
}
else
{
return false;
}
};
}
然后我有一个TextBlock,它绑定到DataGrid 的Items 集合,如下所示:
<StackPanel Grid.Row="0"
Margin="215,0,0,5"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Orientation="Horizontal">
<TextBlock Style="{StaticResource SmallTextBlockStyle}" Text="{Binding ElementName=dgClients, Path=Items.Count}" />
<TextBlock Style="{StaticResource SmallTextBlockStyle}"
Text="{Binding ElementName=dgClients, Path=Items.Count, Converter={StaticResource ClientSingleOrPluralConverter}, StringFormat={} {0}}" />
</StackPanel>
这工作正常,每次过滤DataGrid,值都会相应改变。
但是,我有另一个TextBlock 绑定到DataGrid 的Items 集合,它负责显示显示数据的总和,而这个没有更新!
<TextBlock Margin="5"
FontWeight="Bold"
Text="{Binding ElementName=dgClients,
Path=Items,
Converter={StaticResource CalculateSumConvertor},
StringFormat={}{0:C}}" />
CalculateSumConvertor 只在DataGrid 的绑定处被命中一次,然后就不再被命中了。
这是转换器:
public class CalculateSumConvertor: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var clients = value as ItemCollection;
if (clients != null)
{
return clients.Cast<Client>().Sum(c => c.FieldToSum);
}
else
{
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
我在这里做错了吗?
【问题讨论】:
-
这是因为 DataGrid 不会通知其项目的更改。为什么不能直接将文本框绑定到原始集合?
-
我想尽可能地尊重 MVVM,所以在我的理解中,过滤
CollectionViewSource是一个视图问题。我知道一个解决方案可能是直接在我的 ViewModel 中公开CollectionViewSource对象,但如果可能的话,我更愿意这样做。