Вот исходный код сортировки ValidationSummaryItem, надеюсь, он вам поможет
/// <summary>
/// Compare ValidationSummaryItems for display in the ValidationSummary
/// </summary>
/// <param name="x">The first reference used for comparison.</param>
/// <param name="y">The second reference used for comparison.</param>
/// <returns>The result of the comparison check between the two references.</returns>
internal static int CompareValidationSummaryItems(ValidationSummaryItem x, ValidationSummaryItem y)
{
int returnVal;
if (!ReferencesAreValid(x, y, out returnVal))
{
// Do a null comparison check if one (or both) are null
return returnVal;
}
// Compare ErrorSource
if (TryCompareReferences(x.ItemType, y.ItemType, out returnVal))
{
return returnVal;
}
// Compare Control
Control controlX = x.Sources.Count > 0 ? x.Sources[0].Control : null;
Control controlY = y.Sources.Count > 0 ? y.Sources[0].Control : null;
if (controlX != controlY)
{
if (!ReferencesAreValid(controlX, controlY, out returnVal))
{
// Do a null comparison check if one is null
return returnVal;
}
// Both are controls
if (controlX.TabIndex != controlY.TabIndex)
{
// Sort by TabIndex
return controlX.TabIndex.CompareTo(controlY.TabIndex);
}
// Both share the same parent, sort by index
returnVal = SortByVisualTreeOrdering(controlX, controlY);
if (returnVal != 0)
{
return returnVal;
}
// TabIndexes and ordering are the same, move to next check
if (TryCompareReferences(controlX.Name, controlY.Name, out returnVal))
{
return returnVal;
}
}
// If we reached this point, we could not compare by Control, TabIndex, nor Name.
// Compare by MessageHeader
if (TryCompareReferences(x.MessageHeader, y.MessageHeader, out returnVal))
{
return returnVal;
}
// Compare by ErrorMessage
TryCompareReferences(x.Message, y.Message, out returnVal);
return returnVal;
}