On RowValidating, when a GridViewCellValidationResult is added with a PropertyName such as "Hours", and a column that precedes the Hours column has a binding path of say "SourceHours", the GridView logic incorrectly does a .Contains() on the PropertyName to get the cell, which leads to the SourceHours column being highlighted as the one with the validation error, instead of the Hours column.
I'm using Telerik.Windows.Controls.GridView, Version=2015.3.1104.45, and the offending method is Telerik.Windows.Controls.GridView.GridViewRow.TryGetCellFromPropertyName.
Here's the relevant XAML:
<telerik:GridViewDataColumn Header="Source Hours" DataMemberBinding="{Binding SourceHours}" DataFormatString="n" TextAlignment="Right" />
<telerik:GridViewDataColumn Header="Hours" DataMemberBinding="{Binding Hours}" DataFormatString="n" TextAlignment="Right" />
And here is how I'm adding the GridViewCellValidationResult in the RowValidating event handler:
if (attendance.Hours == 0m) {
e.ValidationResults.Add(new GridViewCellValidationResult { PropertyName = "Hours", ErrorMessage = "Hours cannot be zero."});
}
And this is why it's failing ( the Contains(this.propertyName) part):
internal bool TryGetCellFromPropertyName(string propertyName, out GridViewCell gridViewCell)
{
Func<GridViewBoundColumnBase, bool> func = (GridViewBoundColumnBase c) => c.GetDataMemberName().Contains(this.propertyName);
GridViewDataControl gridViewDataControl = base.GridViewDataControl;
if (string.IsNullOrEmpty(propertyName) || gridViewDataControl == null)
{
gridViewCell = null;
return false;
}
gridViewCell = (
from c in base.Cells.OfType<GridViewCell>()
where c.DataColumn != null
select c).FirstOrDefault<GridViewCell>((GridViewCell c) => func(c.DataColumn));
return gridViewCell != null;
}
If it instead was coded as c.GetDataMemberName() == this.propertyName (or similarly ignoring case if desired), it seems to me that it would work as expected.
For now I will use a UniqueName to get around the issue, but I wanted to bring it to Telerik's attention.