Files
BeWoPlaner/BeWo/Validation/AttributeValidator.cs

64 lines
2.5 KiB
C#

using System.Globalization;
using System.Reflection;
using System.Windows.Controls;
using System.Windows.Data;
using BS.Shared.Extensions;
namespace BeWo.Validation
{
public class AttributeValidator : ValidationRule
{
public BindingExpression ExpressionToValidate { get; set; }
public override ValidationResult Validate(object pValue, CultureInfo pCultureInfo)
{
bool lValid = true;
if (this.ExpressionToValidate != null)
{
PropertyInfo lPropInfo = null;
object lCurrentObject = this.ExpressionToValidate.DataItem;
// Claude: DataItem des Bindings und Eltern-Objekt des Ziel-Propertys festhalten,
// damit kontextabhaengige Regeln den Klientenbezug auswerten koennen.
// Bei "PrototypeVM.Notice" ist das DataItem die ServiceRecordListVM (kennt
// WithoutClient), bei "Notice" in den EditViews die ServiceRecordVM selbst.
object lDataItem = lCurrentObject;
object lOwner = lCurrentObject;
if (lCurrentObject != null)
{
foreach (var iPropName in this.ExpressionToValidate.ParentBinding.Path.Path.Split("."))
{
lOwner = lCurrentObject; // Claude: vor dem GetValue merken
lPropInfo = lCurrentObject.GetType().GetProperty(iPropName);
lCurrentObject = lPropInfo.GetValue(lCurrentObject, null);
}
}
if (lPropInfo != null)
{
var lAttributes = lPropInfo.GetCustomAttributes(typeof(ValidationAttribute), true);
if (lAttributes.Length > 0)
{
// Claude: DataItem hat Vorrang, weil dort der View-Zustand liegt
// (ServiceRecordListVM.WithoutClient); sonst greift das Eltern-Objekt.
var lContext = (lDataItem as ICustomerRelatedContext)
?? (lOwner as ICustomerRelatedContext);
lValid = ((ValidationAttribute) lAttributes[0]).Validate(pValue, lContext);
}
}
}
if (!lValid)
{
}
// TODO: Nachricht, am besten als Property im ValidationAttribut
return new ValidationResult(lValid, null);
}
}
}