使用 CollectionViewSource 和 DataBinding 的 WPF 分组

标签 wpf data-binding collectionviewsource

我将 CollectionViewSource 绑定(bind)到 ListView 以对项目进行分组。这一切都很好,除非我更新 ObservableCollection CollectionViewSource 所基于的。如果我更新集合中某个对象的值,UI 永远不会更新。这是一个例子:

<ListView x:Name="MyListView" Margin="0,0,0,65">
    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Margin" Value="0,0,0,5"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type GroupItem}">
                                <Expander IsExpanded="true" BorderBrush="#FFA4B97F" BorderThickness="0,0,0,1">
                                    <Expander.Header>
                                        <DockPanel>
                                            <TextBlock FontWeight="Bold" Text="{Binding Name}" Margin="5,0,0,0" Width="80"/>
                                            <TextBlock FontWeight="Bold" Width="60" TextAlignment="Center" Margin="16,0,0,0" Text="{Binding Items, Converter={StaticResource Converter2}}" />
                                        </DockPanel>
                                    </Expander.Header>
                                    <ItemsPresenter />
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListView.GroupStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="300" Header="Amount" >
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Amount}" Margin="80,0,0,0"/>
                    </DataTemplate>
                 </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

您会注意到它正在调用组中的转换器并为其提供项目集合。这样转换器就可以计算行的平均值并返回该结果:

public class AverageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        IEnumerable<object> rows = (IEnumerable<object>) value;
        double average = rows.Average(a => ((DisplayRow) a).Amount);
        return average;
    }

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

在后面的代码中,我添加了行并创建了 CollectionViewSource:

私有(private)只读 ObservableCollection displayRows = new ObservableCollection();

public Window1()
{
    InitializeComponent();

    displayRows.Add(new DisplayRow { Title = "Sales", Amount=16} );
    displayRows.Add(new DisplayRow { Title = "Marketing", Amount=14} );
    displayRows.Add(new DisplayRow { Title = "Technology", Amount=13} );
    displayRows.Add(new DisplayRow { Title = "Sales", Amount=11} );
    displayRows.Add(new DisplayRow { Title = "Marketing", Amount=13} );
    displayRows.Add(new DisplayRow { Title = "Technology", Amount=12} );
    CollectionViewSource viewSource = new CollectionViewSource { Source = displayRows };
    viewSource.GroupDescriptions.Add(new PropertyGroupDescription("Title"));
    MyListView.ItemsSource = viewSource.View;
}

DisplayRow 对象实现了INotifyPropertyChanged,只是一个简单的类。

一切正常,显示是我想要的方式,但如果我更改 ObservableCollection 中的值,UI 不会更改。

如果我向集合中添加一个元素,我可以看到它出现在屏幕上,但永远不会调用转换器来重新计算平均值。有什么想法吗?

最佳答案

我找到了解决这个问题的破解方法。

private CollectionViewSource _viewSource;

private void ModifyData()
{
    // Modify some data

    // This will cause the ListView to refresh its data and update the UI
    // and also cause the converter to be called to reformat the data.
    _viewSource.View.Refresh();
}

希望对您有所帮助。

关于使用 CollectionViewSource 和 DataBinding 的 WPF 分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1608015/

相关文章:

c# - 使用 Parallel 创建绑定(bind)项时 CollectionViewSource.SortDescriptions 不起作用

wpf - 应用 CollectionView 筛选器后如何绑定(bind) DataGrid 行计数?

c# - 在 xaml 中使用 backgroundworker 和绑定(bind)时 UI 不会更新

wpf - 将 Wpf HierarchicalDataTemplate ItemsSource 绑定(bind)到字典中的 CollectionViewSource?

c# - ObservableCollection.SetItem() 由于其保护级别而无法访问

c# - 处理绑定(bind) MVVM 属性中未捕获的异常

c# - 使用 x :Bind 设置 GridView 项目源的 UWP 问题

c# - DevExpress DataBinding,添加新记录

c# - (ViewModel)DataContext 返回 null

c# - 可编辑的 WPF 列表框