如何防止Item添加到DataGrid?

时间:2017-12-20 17:31:01

标签: c# wpf 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>();
}

View

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

我已经尝试了

...在处理时从DataGridItemsSource删除自动创建的对象:

...但总是会收到例外情况:

  
      
  • System.InvalidOperationException:在AddNew或EditItem事务期间不允许删除”。
  •   
  • System.InvalidOperationException:在CollectionChanged事件期间无法更改ObservableCollection。”
  •   
  • System.InvalidOperationException:当ItemsSource正在使用时,操作无效。请改为使用ItemsControl.ItemsSource访问和修改元素。”
  •   

我的问题

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

编辑:

@picnic8AddingNewItem事件未提供任何形式的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?
}

2 个答案:

答案 0 :(得分:4)

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

您可以做的是在DataGrid.RowEditEndingDataGridRowEditEndingEventArgs.EditAction并使用DataGridEditAction.Commit方法处理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();
            }
        }
    }
}

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

答案 1 :(得分:-1)

在您的虚拟机中,订阅AddingNewItem事件并检查您的状况。如果条件失败,您可以停止操作。

var datagrid.AddingNewItem += HandleOnAddingNewItem;

public void HandleOnAddingNewItem(object sender, RoutedEventArgs e)
{
    if(myConditionIsTrue)
    {
        e.Handled = true; // This will stop the bubbling/tunneling of the event
    }
}