WPF: Detect row validation errors in C# code
I want to achieve a pretty simple task, but none of the solutions here on SO or otherwise found have helped me so far:
I have a WPF DataGrid
, which is bound to a typed data set. When I click the OK button in my window, I want to detect whether there are currently any row validation errors. I want to show a message box and tell the user to resolve these errors.
How can I achieve this?
EDIT
To make my question a bit more precise:The typed dataset I'm binding to is a simple data set that contains a table. The tables is filled from a call to a WCF service and there are 5 text columns in the table. Some of these columns have length constraints (for example, one column may only take 5 characters).
The ItemsSource
of my GridView
is set in code as follows:
dgvData.ItemsSource = m_dataModel.TableName;
If I enter some text into the columns, all is well. Entering more than 5 characters into said column, the red row error marker is displayed next to the row. I am not doing any custom validation (yet).
I can see the red exclamation mark, but I'm not able to determine in code whether it is visible or not. I've tried to:
- Use the data set's
HasErrors
property (returnsfalse
) Validation.GetHasErrors(dgvData)
returnsfalse
as well- the soluction H.B.'s mentioned in his comment, but it didn't work
I'm a开发者_如何学Pythont a loss here - there must be a simple way of doing this?
OK, I've worked it out. The following does what I want:
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;
}
In the code for my "OK" button I do:
for (int i = 0; i < dgvData.Items.Count; i++)
{
DataGridRow row = GetRow(dgvData, i);
if (row != null && Validation.GetHasError(row))
{
hasDataGridErrors = true;
break;
}
}
Why dont you catch the attached bubbling routed event Validation.Error
on your data grid?
<DataGrid x:Name="mydataGrid" Validation.Error="MyValidationErrorHandler" ... />
Make sure you have NotifyOnValidationError=true
in your bindings. This way you would know that error has been raised and show that in your messagebox.
But do you really "know" there are errors on the datagrid? I mean do you see the errors highlighted using red border , tooltips, row validation error template etc? Isnt that sufficient to indicate to user?
Cant you use
Validation.GetHasError(mydataGrid)
to check if its in error?
This seems a near duplicate of this [question]: (Checking If Any WPF DataGrid Cell Has Error).
Here's an answer that's more XAMly. It relies on the fact that when an error template is shown its IsVisible property toggles.
Just create a ValidationErrorTemplate for the DataGridRow [1]: (http://msdn.microsoft.com/en-us/library/ee622975.aspx)
Create 2 attacheded properties. The value of the one attached property is the DataGrid itself,
local:DataGridValidator.DataGridToMarkForValidationErrors="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}}"
Attach the property to the root control of the ValidationErrorTemplate.
In the callback for the attached property set the 2nd property on the DataGrid to show whether it has errors:
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);
};
}
Now the DataGrid has a property (IsFreeOfValidatoionErrorsProperty) showing whether it has errors or not. I made the property default positive so I could easily AND it with my VM IsDirty/CanSave property.
精彩评论