我的问题
我试图阻止用户在使用内置的.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}" />
我已经试过了
…处理时从DataGrid
的ItemsSource
中删除自动创建的对象:
> 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.EditAction
为DataGridEditAction.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
方法.