我想完成一个非常简单的任务,但是到目前为止,在SO或其他地方找到的解决方案都没有帮助我:
我有一个WPF DataGrid
,它绑定到一个类型化数据集。当我单击窗口中的OK按钮时,我想检测当前是否有任何行验证错误。我想显示一个消息框,告诉用户解决这些错误。
我怎样才能做到这一点?
编辑
让我的问题更精确一点:
我绑定的类型化数据集是一个包含表的简单数据集。表格由对WCF服务的调用填充,表格中有5个文本列。其中一些列有长度限制(例如,一列可能只包含5个字符)。
我的GridView
的ItemsSource
在代码中设置如下:
dgvData.ItemsSource = m_dataModel.TableName;
如果我在列中输入一些文本,一切正常。在列中输入超过5个字符,行旁边会显示红色的行错误标记。我还没有做任何自定义验证。
我可以看到红色感叹号,但我不能确定在代码中它是否可见。我试过:
- 使用数据集的
HasErrors
属性(返回false
) -
Validation.GetHasErrors(dgvData)
也返回false
- 解决方案H.B.在他的评论中提到,但它没有工作
我不明白了——一定有简单的方法来做这件事吧?
好了,我算出来了。下面是我想要的:
public static DataGridRow GetRow(DataGrid grid, int index)
{
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// May be virtualized, bring into view and try again.
grid.UpdateLayout();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
在我的"OK"按钮代码中,我这样做:
for (int i = 0; i < dgvData.Items.Count; i++)
{
DataGridRow row = GetRow(dgvData, i);
if (row != null && Validation.GetHasError(row))
{
hasDataGridErrors = true;
break;
}
}
为什么不在数据网格上捕获附加的冒泡路由事件Validation.Error
?
<DataGrid x:Name="mydataGrid" Validation.Error="MyValidationErrorHandler" ... />
确保你的绑定中有NotifyOnValidationError=true
。这样你就会知道错误已经出现,并在你的消息框中显示出来。
但是你真的"知道"数据网格上有错误吗?我的意思是,你看到用红色边框、工具提示、行验证错误模板等突出显示的错误了吗?这还不足以告诉用户吗?
Validation.GetHasError(mydataGrid)
检查它是否出错?
这似乎是一个几乎重复的[问题]:(检查是否有任何WPF DataGrid Cell有错误)。
这里有一个更有趣的答案。它依赖于这样一个事实:当显示错误模板时,它的IsVisible属性会切换。
为DataGridRow [1]: (http://msdn.microsoft.com/en-us/library/ee622975.aspx)创建一个ValidationErrorTemplate
创建两个附加属性。附加属性的值是DataGrid本身,
local:DataGridValidator.DataGridToMarkForValidationErrors="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}}"
将属性附加到ValidationErrorTemplate的根控件上。
在附加属性的回调中设置DataGrid上的第二个属性,以显示它是否有错误:
private static void DataGridPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
var fe = dependencyObject as FrameworkElement;
var target = args.NewValue as DependencyObject;
if (fe != null && target != null)
{
target.SetValue(IsFreeOfValidatoionErrorsProperty, !fe.IsVisible);
fe.IsVisibleChanged += (_1, _) =>
{
target.SetValue(IsFreeOfValidatoionErrorsProperty, !fe.IsVisible);
};
}
现在DataGrid有一个属性(isfreeofvalidationerrorsproperty)显示它是否有错误。我使属性默认为正,所以我可以很容易地和它与我的VM IsDirty/CanSave属性。