WPF,EF:在datagrid,mvvm中显示和保存行的顺序

时间:2014-12-01 08:19:42

标签: c# wpf mvvm datagrid

我的用户希望能够在一些数据网格和其他列表控件中重新排列行。已存在具有SortOrder列(整数)的现有数据库。我使用实体框架6.1。我的视图需要显示此列所订购的项目,并且当用户单击" save"时,必须将对订单的任何更改保存到数据库中。和context.SaveChanges被称为

到目前为止,我最好的尝试是将一个SortOrder列添加到我的datagrid并按它排序(我打算让它以某种方式隐藏...),在我的viewmodel中为up / down调用命令附加PreviewKeyDown事件,反过来更新SortOrder值。但是,即使我执行RaisePropertyChanged(" MyDataGridItemSource"),数据网格也不会更新,我已经尝试设置mode = twoway,NotifyBySource = true,NotifyByTarget = true。完全重新设置MyDataGridItemSource将更新SortOrder列的值,但它不会根据它重新排列行,而且我也会丢失我不需要的选择。

对于将数据库排序列映射到这样的控制器,您有什么好的建议吗?

1 个答案:

答案 0 :(得分:1)

最简单的方法是将集合包装在CollectionViewSource

首先,您需要确保集合项实现INotifyPropertyChanged,并且只要PropertyChanged属性发生更改,就会引发SortOrder事件。然后像这样定义集合视图源:

<CollectionViewSource x:Key="CollectionView" Source="{Binding Collection}" IsLiveSortingRequested="True">
    <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="SortOrder" Direction="Ascending"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

其中xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase",并将其放在DataGrid的祖先控件的资源字典中(例如在Window.ResourcesUserControl.Resources中)。最后,将已定义的集合视图源设置为DataGrid的项目来源:

<DataGrid ItemsSource="{Binding Source={StaticResource CollectionView}}">
    ...
</DataGrid>

现在,只要在任何项目上更改了SortOrder属性,就应该相应地更新UI。

<强>更新

如果项目未实施INotifyPropertyChanged,则上述解决方案将无效。您可能需要考虑创建一个包装类,该类将公开必要的属性并实现INotifyPropertyChanged(此设计模式通常称为“装饰模式”)。但是,如果它不是一个选项,您可以在视图模型上定义集合视图,并将其绑定到集合本身,并在对项目进行任何更改时手动刷新视图。以下是它的外观示例:

public IEnumerable<Item> Collection 
{
    get { ... }
    set
    {
        //store the value in the backing field
        if (value != null)
        {
            CollectionView = CollectionViewSource.GetDefaultView(value);
            CollectionView.SortDescriptions.Add(new SortDescription
            {
                Direction = ListSortDirection.Ascending,
                PropertyName = "SortOrder",
            });
        }
        else
            CollectionView = null;
    }
}

public ICollectionView CollectionView
{
    get { ... }
    set
    {
        //store the value in the backing field and raise PropertyChanged
    }
}

在XAML中,绑定到集合视图:

<DataGrid ItemsSource="{Binding CollectionView}">
    ...
</DataGrid>

然后,每当您对项目进行更改时,请在完成后调用CollectionView.Refresh()并更新UI。