在AddNew或EditItem事务mvvm期间不允许WPF DataGrid“刷新”

时间:2013-11-25 22:22:07

标签: wpf mvvm wpfdatagrid

我有以下网格

    <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>

然后我有一个seachCommand,在viewmodel中对collectionViewSource FilteredModel执行搜索,然后调用

this.FilteredModels.View.Refresh();

当用户检查一些复选框并将网格发送到editmode然后执行搜索时,我们会收到以下错误

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

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

谢谢!

3 个答案:

答案 0 :(得分:23)

我知道回答太晚了......但对于正在寻找答案的人来说

按照这样的顺序使用cancelEdit或commitEdit方法两次

// for commit

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

//取消

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

答案 1 :(得分:4)

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

答案 2 :(得分:0)

有一个干净的MVVM解决方案。首先,您的ViewModels必须实现IEditableObject接口(没有操作就足够了)。但是,这还不够,因为DataGrid将不会收听IEditableObject.CancelEdit
另一个问题是, ICollectionView IEditableCollectionView 都不实现另一个。虽然只有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();
   }
}

或者换句话说,您可以将ICollectionView强制转换为IEditableCollectionView并首先调用CancelEdit()