我正在尝试阻止用户在使用内置的.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}" />
...在处理时从DataGrid
的ItemsSource
删除自动创建的对象:
DataGrid.AddingNewItem
INotifyCollectionChanged.CollectionChanged
PageViewModel.PageItems
IEditableCollectionView.CancelNew
DataGrid.OnItemsChanged
...但总是会收到例外情况:
- “ System.InvalidOperationException:在AddNew或EditItem事务期间不允许删除”。
- “ System.InvalidOperationException:在CollectionChanged事件期间无法更改ObservableCollection。”
- “ System.InvalidOperationException:当ItemsSource正在使用时,操作无效。请改为使用ItemsControl.ItemsSource访问和修改元素。”
如何阻止将新创建的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?
}
答案 0 :(得分:4)
您不能也不应该阻止添加到底层集合,因为当最终用户开始输入新行时,DataGrid
将创建并添加新的PageItemViewModel
对象在那时使用默认值初始化。
您可以做的是在DataGrid.RowEditEnding
为DataGridRowEditEndingEventArgs.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
}
}