如何防止Item添加到DataGrid?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何防止Item添加到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}" />
我已经试过了
...在处理时从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
。
EDIT:
@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
对象,该对象在此时使用默认值进行初始化。
你可以做的是通过在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();
}
}
}
}
一个重要的细节是在将当前编辑器值推送到数据源之前触发了RowEditEnding
事件,因此您需要在执行验证之前手动执行此操作。我已经使用了BindingGroup.CommitEdit
方法。
在您的VM中,订阅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
}
}
以上是关于如何防止Item添加到DataGrid?的主要内容,如果未能解决你的问题,请参考以下文章
如何防止 ComboBox 中的 NewItemPlaceholder 行绑定到与 WPF 中的 DataGrid 相同的 DataTable