C# WPF DataGrid-验证错误后如何取消编辑行?
我想在用户单击时取消行中的更改✖ 按钮C# WPF DataGrid-验证错误后如何取消编辑行?,c#,wpf,datagrid,C#,Wpf,Datagrid,我想在用户单击时取消行中的更改✖ 按钮 private void CancelChangesButton_单击(对象发送方,路由目标) { datagrid.CancelEdit(); } CancelEdit()非常有效,直到。。。my DateConverter无法转换回字符串。当ViewModel的属性设置程序引发异常时,也会发生相同的行为。 我不能在DataGrid中做任何事情。唯一的方法是在光标位于红色单元格中时按ESC键 我试着做其他事情: datagrid.CancelEdit
private void CancelChangesButton_单击(对象发送方,路由目标)
{
datagrid.CancelEdit();
}
CancelEdit()非常有效,直到。。。my DateConverter无法转换回字符串。当ViewModel的属性设置程序引发异常时,也会发生相同的行为。
我不能在DataGrid中做任何事情。唯一的方法是在光标位于红色单元格中时按ESC键
我试着做其他事情:
datagrid.CancelEdit(DataGridEditingUnit.Row);
datagrid.CancelEdit(DataGridEditingUnit.Cell);
datagrid.committedit();
datagrid.IsReadOnly=true;
//添加新项目
什么也没发生
因此,我开始挖掘.NET Framework的源代码,我发现:
公共类数据网格:多选择器
...
公共布尔取消编辑(DataGridEditingUnit editingUnit)
{
返回EndEdit(CancelEditCommand,CurrentCellContainer,editingUnit,true);
}
这里最重要的是CurrentCellContainer,它从CurrentCell获取值。接下来,我发现CurrentCell正在跟踪焦点。当我点击✖ 按钮,CurrentCell将更改为Action列中的单元格,当我单击DataGrid外部时,CurrentCell将更改为null
因此,我必须将CurrentCell更改为带有验证错误的单元格,然后调用CancelEdit()。
我认为对吗
如何查找存在验证错误的所有单元格?
是否有其他方法取消编辑?红细胞显示验证错误。只要存在验证错误(用户按Escape键除外),就不能取消编辑模式 唯一的解决方案是通过简单地恢复输入手动解决错误 算法如下:
文本框
TextBox.Text的绑定源(数据项)属性
文本框
,它将触发重新验证并定义取消的目标单元格李>
private void CancelChangesButton_Click(object sender, RoutedEventArgs e)
{
DependencyObject cellItemContainer = this.datagrid.ItemContainerGenerator.ContainerFromItem(
(this.datagrid.CurrentCell.Item as SomethingItem));
// If the current cell has validation errors find the edit TextBox child control
if (Validation.GetHasError(cellItemContainer) && TryFindChildElement(cellItemContainer, out TextBox editTextBox))
{
// Get the property name of he binding source
var propertyName = (editTextBox.BindingGroup.BindingExpressions.FirstOrDefault() as BindingExpression)?.ResolvedSourcePropertyName ?? string.Empty;
// Use reflection to get the value of the binding source
object value = this.datagrid.CurrentCell.Item.GetType().GetProperty(propertyName).GetValue(this.datagrid.CurrentCell.Item);
// Check which ToString() to invoke
editTextBox.Text = value is DateTime date
? date.ToShortDateString()
: value.ToString();
// Trigger validation and define which cell to cancel the edit
// This is required because the edit TexBox lost focus
Keyboard.Focus(editTextBox);
}
this.datagrid.CancelEdit();
}
// Traverses the visual tree to find a child element of type TElement
private bool TryFindVisualChild<TChild>(DependencyObject parent, out TChild resultElement) where TChild : DependencyObject
{
resultElement = null;
for (var childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(parent); childIndex++)
{
DependencyObject childElement = VisualTreeHelper.GetChild(parent, childIndex);
if (childElement is Popup popup)
{
childElement = popup.Child;
}
if (childElement is TChild)
{
resultElement = childElement as TChild;
return true;
}
if (TryFindVisualChild(childElement, out resultElement))
{
return true;
}
}
return false;
}
private void CancelChangesButton_单击(对象发送方,路由目标)
{
DependencyObject cellItemContainer=this.datagrid.ItemContainerGenerator.ContainerFromItem(
(this.datagrid.CurrentCell.Item作为SomethingItem));
//如果当前单元格存在验证错误,请查找编辑文本框子控件
if(Validation.GetHasError(cellItemContainer)和&TryFindChildElement(cellItemContainer,out TextBox editTextBox))
{
//获取绑定源的属性名称
var propertyName=(editTextBox.BindingGroup.BindingExpressions.FirstOrDefault()作为BindingExpression)?。ResolvedSourcePropertyName??string.Empty;
//使用反射获取绑定源的值
对象值=this.datagrid.CurrentCell.Item.GetType().GetProperty(propertyName).GetValue(this.datagrid.CurrentCell.Item);
//检查要调用哪个ToString()
editTextBox.Text=值为日期时间日期
?date.ToShortDateString()
:value.ToString();
//触发验证并定义要取消编辑的单元格
//这是必需的,因为编辑框失去焦点
键盘。焦点(编辑文本框);
}
this.datagrid.CancelEdit();
}
//遍历可视化树以查找TElement类型的子元素
private bool TryFindVisualChild(DependencyObject父对象,out TChild resultElement),其中TChild:DependencyObject
{
resultElement=null;
对于(var childIndex=0;childIndex
我意识到我不需要找到有验证错误的单元格。我只需要对所有单元格调用CancelEdit()
private void CancelChangesButton_单击(对象发送方,路由目标)
{
var cc=dataGrid.CurrentCell;
foreach(datagrid.Columns中的var col)
{
datagrid.CurrentCell=新的DataGridCellInfo(datagrid.CurrentItem,col);
datagrid.CancelEdit();
}
dataGrid.CurrentCell=cc;
}
它还可以使用DataGridTemplateColumn。
但是,如果您想找到哪些单元格包含验证错误,则需要深入查看。多亏了@BionicCode,我找到了一个解决方案 您可以获得可视化DataGridRow:
DataGridRow行=(DataGridRow)datagrid.ItemContainerGenerator.ContainerFromItem(item);
然后,您可以检查错误:
if(Validation.gethasrerror(行))
您还可以访问行.BindingGroup
,其中包含此行中的所有绑定(.BindingExpressions),以及许多其他信息(IsDirty、ValidationErrors、ValidationRules、CancelEdit()
但是,当您想要检查单元格中的错误时,这并不是那么容易。不幸的是,DataGridCell不包含有关错误的信息,Validation.GetHasError(单元格)
不工作。您需要更深入地查看可视化树
private void cancelchangescellshoodingerror()
{
SomethingItem item=datagrid.CurrentItem作为SomethingItem;
DataGridRow行=(DataGridRow)datagrid.ItemContainerGenerator.ContainerF