DevExpress XAF / XPO Custom Validation

Date: 2023-04-17

The trick is to use an extra property, decorate it with [Browsable(false)] and [RuleFromBoolProperty]

[NonPersistent]
[ModelDefault("DisplayFormat", "{0:g}")]
[ModelDefault("EditMask", "g")]
[ModelDefault("Caption", "Start")]
[RuleRequiredField("KlantMelding.Start.Required", DefaultContexts.Save, "Voer de start/aanvangstijd in")]
[VisibleInDetailView(false)]
public DateTime Start
{
    get => _startdatum + _starttijd;
    set
    {
        StartDatum = value.Date;
        StartTijd = value.TimeOfDay;
    }
}

[Browsable(false)]
[RuleFromBoolProperty("Storing.StartTimeValid", DefaultContexts.Save, "De start/aanvangstijd moet in het verleden liggen")]
public bool StartTimeValid => Start < DateTime.Now;

// 2nd example:

[Association("KlantMelding-Klant")]
[ModelDefault("Caption", "Klanten")]
[DataSourceProperty("BeschikbareKlanten")]
[DataSourceCriteria("DebiteurStatus != 7 && !IsNull(Relatie)")]
public XPCollection<Klant> Klanten => GetCollection<Klant>(nameof(Klanten));


[Browsable(false)]
[RuleFromBoolProperty("KlantMelding.Klanten.Required", DefaultContexts.Save, "Er moet minimaal 1 klant worden geselecteerd")]
public bool KlantenValid => Klanten.Count() > 0;


76850cookie-checkDevExpress XAF / XPO Custom Validation