在 AddNew 或 EditItem 事务 mvvm 期间不允许 WPF DataGrid 'Refresh'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20204592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:07:29  来源:igfitidea点击:

WPF DataGrid 'Refresh' is not allowed during an AddNew or EditItem transaction mvvm

wpfmvvmwpfdatagrid

提问by twaldron

I have the following grid

我有以下网格

    <DataGrid

        x:Name="TablesDataGrid"
        Grid.Column="0"
        Grid.Row="1"
        ItemsSource="{Binding FilteredModels.View}"
        AlternationCount="2"
        AutoGenerateColumns="False"
        CanUserSortColumns="True"
        CanUserReorderColumns="False"
  CanUserDeleteRows="False"
  CanUserAddRows="False"
  SelectionMode="Extended"
        IsReadOnly="False"
  SelectionUnit="FullRow"
        RowHeight="25"
  HorizontalAlignment="Stretch"
  ColumnWidth="Auto">
            <DataGrid.Columns >
                <DataGridCheckBoxColumn Width="*" Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  IsReadOnly="False">
                    <DataGridCheckBoxColumn.HeaderTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.CheckAll}"/>
                        </DataTemplate>
                    </DataGridCheckBoxColumn.HeaderTemplate>
                </DataGridCheckBoxColumn>
                <DataGridTextColumn Header="Source Table" Binding="{Binding SourceTableFullName}" Width="4*"></DataGridTextColumn>
                <DataGridTextColumn Header="EDW Schema"  Binding="{Binding SchemaName}" Width="2*"></DataGridTextColumn>
                <DataGridTextColumn Header="EDW Table" Binding="{Binding TableName}" Width="4*"></DataGridTextColumn>
                <DataGridTextColumn Header="Status" Binding="{Binding Status}" Width="*"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

and then i have a seachCommand with performs the search on the collectionViewSource FilteredModels in the viewmodel and then calls

然后我有一个 seachCommand 对视图模型中的 collectionViewSource FilteredModels 执行搜索,然后调用

this.FilteredModels.View.Refresh();

when a user checks a few of the checkboxes and sends the grid into editmode and then performs a search we get the following error

当用户选中几个复选框并将网格发送到编辑模式然后执行搜索时,我们会收到以下错误

WPF DataGrid 'Refresh' is not allowed during an AddNew or EditItem transaction

is there a way to force the grid out of edit mode when a check box is checked or maybe even when the seach button is clicked or some other fix for this?

有没有办法在选中复选框时强制网格退出编辑模式,或者甚至在单击搜索按钮或其他一些修复方法时?

thanks!

谢谢!

回答by Saad Abdullah

I know its too late to answer...but for someone who is looking for answer

我知道现在回答已经太晚了……但对于正在寻找答案的人

use cancelEdit or commitEdit method two times in a sequence like this

在这样的序列中使用 cancelEdit 或 commitEdit 方法两次

//for commit

//提交

this.datagrid_layers.CommitEdit();
this.datagrid_layers.CommitEdit();

//for cancel

//取消

this.datagrid_layers.CancelEdit();
this.datagrid_layers.CancelEdit();

回答by jfin3204

you should be able to cast the selected item to IEditableObject and call EndEdit on it, or call the grids CancelEdit method.

您应该能够将所选项目转换为 IEditableObject 并在其上调用 EndEdit,或调用网格 CancelEdit 方法。

回答by wondra

There is a clean MVVM solution to the problem. First off, your ViewModels must implement IEditableObjectinterface (no-op should be enough). That, however, is not enough since the DataGridwill not listen to IEditableObject.CancelEdit.
Another problem is, that neither ICollectionViewnor IEditableCollectionViewimplement the other one. While only ICollectionViewcan refresh, only IEditableCollectionViewcan commit/cancel. Luckily collection view returned by CollectionViewSource.GetDefaultViewimplements both:

这个问题有一个干净的 MVVM 解决方案。首先,您的 ViewModel 必须实现IEditableObject接口(无操作就足够了)。然而,这还不够,因为他们DataGrid不会听IEditableObject.CancelEdit
另一个问题是,ICollectionViewIEditableCollectionView都没有实现另一个。虽然只能ICollectionView刷新,只能IEditableCollectionView提交/取消。幸运的是,由CollectionViewSource.GetDefaultView实现两个返回的集合视图:

// ViewModel.cs
public class ItemVM : IEditableObject, INotifyPropertyChanged { }

public class ModuleVM : INotifyPropertyChanged {
   ICollectionView Items { get; }

   public ModuleVM(ObservableCollection<ItemVM> items) {
      Items = CollectionViewSource.GetDefaultView(items);
   }

   public void RefreshSafely() {
      ((IEditableCollectionView)Items).CancelEdit(); // alterantively, CommitEdit()
      Items.Refresh();
   }
}

Or in other words, you can cast ICollectionViewto IEditableCollectionViewand call CancelEdit()first.

或者换句话说,您可以首先投射ICollectionViewIEditableCollectionView并调用CancelEdit()