c# – 如何防止将项添加到DataGrid?

我的问题

我试图阻止用户在使用内置的.NET DataGrid AddNewItem功能时添加空的DataGrid行.因此,当用户尝试提交DataGrid的AddNew事务并将PageItemViewModel.Text保留为空时,它应该从DataGrid中消失.

代码

的ViewModels

public class PageItemViewModel
{
    public string Text { get; set; }
}

public class PageViewModel
{
    public ObservableCollection<PageItemViewModel> PageItems { get; } = new ObservableCollection<PageItemViewModel>();
}

视图

<DataGrid AutoGenerateColumns="True"
          CanUserAddRows="True"
          ItemsSource="{Binding PageItems}" />

我已经试过了

…处理时从DataGridItemsSource中删除自动创建的对象:

> DataGrid.AddingNewItem
> Page 07Model.PageItems的INotifyCollectionChanged.CollectionChanged
> IEditableCollectionView.CancelNew
> DataGrid.OnItemsChanged

…但总是收到例外情况:

  • System.InvalidOperationException: ‘Removing’ is not allowed during an AddNew or EditItem transaction.”
  • System.InvalidOperationException: Cannot change ObservableCollection during a CollectionChanged event.”
  • System.InvalidOperationException: Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead.”

我的问题

如何防止新创建的PageItemViewModel被添加到
ObservableCollection<PageItemViewModel>,当存在给定条件时(在这种情况下:String.IsNullOrWhiteSpace(PageItemViewModel.Text)== true.

编辑:

@picnic8:AddingNewItem事件不提供任何形式的RoutedEventArgs,因此不提供Handled属性.相反,它是AddingNewItemEventArgs.您的代码无效.

private void DataGrid_AddingNewItem(object sender, AddingNewItemEventArgs e)
{
    var viewModel = (PageItemViewModel)e.NewItem;
    bool cancelAddingNewItem = String.IsNullOrWhiteSpace(viewModel.Text) == true;
    // ??? How can i actually stop it from here?
}

解决方法:

您不能也不应该阻止添加到底层集合,因为当最终用户开始在新行中键入时,DataGrid将创建并添加一个新的PageItemViewModel对象,该对象在此时使用默认值进行初始化.

但是,您可以做的是通过在DataGridRowEditEndingEventArgs.EditActionDataGridEditAction.Commit时处理DataGrid.RowEditEnding事件来防止提交该对象,并在验证失败时使用DataGrid.CancelEdit方法有效地删除新对象(或恢复现有对象状态).

private void DataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
    if (e.EditAction == DataGridEditAction.Commit)
    {
        var bindingGroup = e.Row.BindingGroup;
        if (bindingGroup != null && bindingGroup.CommitEdit())
        {
            var item = (PageItemViewModel)e.Row.Item;
            if (string.IsNullOrWhiteSpace(item.Text))
            {
                e.Cancel = true;
                ((DataGrid)sender).CancelEdit();
            }
        }
    }
}

一个重要的细节是在将当前编辑器值推送到数据源之前触发了RowEditEnding事件,因此您需要在执行验证之前手动执行此操作.我已经使用了BindingGroup.CommitEdit方法.

上一篇:c# – 如何在WPF中修改DataGrid垂直滚动条的位置?


下一篇:c# – 双击时停止单元格进入编辑模式