【问题标题】:DataGrid Items collection doesn't always refreshDataGrid Items 集合并不总是刷新
【发布时间】: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,它绑定到DataGridItems 集合,如下所示:

<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 绑定到DataGridItems 集合,它负责显示显示数据的总和,而这个没有更新!

<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 对象,但如果可能的话,我更愿意这样做。

标签: wpf binding datagrid


【解决方案1】:

将您的绑定更改为以下内容并将您的转换器更改为 IMultiValueConverter

    <TextBlock Margin="5"
       FontWeight="Bold">
        <TextBlock.Text>
            <MultiBinding Converter="{StaticResource CalculateSumConvertor}" StringFormat="{}{0:C}">
                <Binding ElementName="dgClients" Path="Items" />
                <Binding ElementName="dgClients" Path="Items.Count" />
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>

转换器:

class CalculateSumConvertor : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var clients = values[0] as ItemCollection;
        ...
    }




}

【讨论】:

  • 确实,它有效,非常感谢,我根本没想到!这是否意味着在MultiBinding 上,一旦Binding 更新,每隔一个Binding 就会重新读取?
  • 实际上,绑定会缓存它们的值并且不会被重新读取,除非被 PropertyChanged 事件强制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多