如何关闭(带有复选框)WPF/MVVM 使用 CollectionViewSource 实现的 DataGrid 分组?

how to turn off (with a checkbox) WPF/MVVM DataGrid grouping that is implemented using CollectionViewSource?

我正在实施数据网格分组。下面是我所做的(省略了扩展器的 GroupStyle):

<CollectionViewSource x:Key="SelectedObjectsViewSource" Source="{Binding SelectedObjectItems}">
    <CollectionViewSource.GroupDescriptions>
       <PropertyGroupDescription PropertyName="TableId"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>


<DataGrid Name="SelectedObjectsGrid" 
     ItemsSource="{Binding Source={StaticResource SelectedObjectsViewSource}}"
     SelectionMode="Extended"
     CanUserAddRows="False"
     AutoGenerateColumns="False">

我想添加一个用户可以打开 off/on 分组的复选框。但我不知道如何在 MVVM

中实现它

您可以在当前视图中创建另一个 DataGrid:

<DataGrid Name="SelectedObjectsGridWithoutGrouping" Visibility="False" 
 ItemsSource="{Binding NewCollection}"
 SelectionMode="Extended"
 CanUserAddRows="False"
 AutoGenerateColumns="False">

之后,您必须在 ViewModel 中创建 NewCollection(其中包含 SelectedObjectItems 集合中的项目,但没有分组),并且当用户更改复选框时,通过更改 Visibility SelectedObjectsGrid 或 SelectedObjectsGridWithoutGrouping 来显示或隐藏其中之一。

我建议您将复选框绑定到 viewmodel 的 bool 属性,其中它的 setter 还设置了指定值之后的 collectionview 的分组状态。就像下面的示例:绑定到复选框状态的 bool 属性 是 GroupView,绑定到数据网格的集合是 View.

C# 视图模型

class ViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private ICollectionView _View;
    public ICollectionView View
    {
        get
        {
            return _View;
        }
        set
        {
            _View = View;
            NotifyPropertyChanged("View");
        }
    }

    private bool _GroupView;
    public bool GroupView
    {
        get
        {
            return _GroupView;
        }
        set
        {
            if (value != _GroupView)
            {
                // Clear Grouping status of the view
                View.GroupDescriptions.Clear();
                if (value)
                {
                    // If true set Grouping status
                    View.GroupDescriptions.Add(new PropertyGroupDescription("TableId"));
                }
                _GroupView = value;
                NotifyPropertyChanged("GroupView");

                // Notify the UI that also the View changed in order to redraw the datagrid with or without grouping
                NotifyPropertyChanged("View");
            }
        }
    }   
}

C# 代码隐藏

public partial class MyWindow : Window
{
    public MyWindow()
    {
        InitializeComponent();
        ViewModel myViewModel = new ViewModel();
        myViewModel.View = .....;
        DataContext = myViewModel;

    }
}

XAML

<StackPanel>
    <CheckBox IsChecked="{Binding GroupView, Mode=TwoWay}"/>
    <DataGrid Name="SelectedObjectsGrid" 
            ItemsSource="{Binding View, Mode=TwoWay}"
            SelectionMode="Extended"
            CanUserAddRows="False"
            AutoGenerateColumns="False"/>
</StackPanel>