Search This Blog
Wednesday, July 30, 2014
Checking if an object is new or not within a criterion string
Typical usage scenarios
I remember registering a corresponding feature request in order to make it easier for XAF developers to accomplish the following types of tasks:a) Validating data fields for new records only; e.g., the scenario from Q440548
b) Implementing different data field appearance for new and saved records; e.g., the color or enabled state as in Q475272
c) Managing Action controls' state for new records via TargetObjectsCriteria
During these years these three scenarios stayed popular among our users (we had several dozens of trackers), so it was a natural decision for us, as framework creators, to make accomplishing this common and proven stuff easier for developers and probably end users.
Existing solutions
Before I introduce the usability improvement, I want to briefly outline a couple of good existing solutions that require writing some custom code to accomplish the tasks above.In short, these are declaring a non-persistent property within your base persistent class that would return Session.IsNewObject(this) from the getter and then using this property in criteria, OR controlling required logic via Controllers and a similar IObjectSpace.IsNewObject method. You can find more technical details in this SC ticket. As I emphasized above, these are still good solutions and you can continue using them, but what would be great is to have something built-in that would allow developers not to write any code for these common scenarios.
Our new solution and its implementation details
Our solution, which is included in the standard delivery starting with v14.1.5 (so you can already access it), is a built-in IsNewObject criteria function, which can be used inside a criteria string; e.g., for the ConditionalAppearance and Validation modules.This function is currently available for XPO users only, and it requires a persistent object instance as a parameter. The exact usage syntax is IsNewObject(This) or IsNewObject(ReferenceProperty),
where "This" is a service XPO keyword referring to the current object instance and "ReferenceProperty" is a reference property of the current object. Here are also some screenshots from the Model Editor depicting the real use by example of the appearance and validation rules:
The implementation of the custom criteria function is pretty straightforward, and I believe that some of you already have something similar in your code:
using System;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp.SystemModule;
namespace DevExpress.ExpressApp.Xpo {
public class IsNewObjectCriteriaOperator : ICustomFunctionOperator {
public const string OperatorName = "IsNewObject";
private static readonly IsNewObjectCriteriaOperator instance = new IsNewObjectCriteriaOperator();
public static void Register() {
CustomFunctionOperatorHelper.Register(instance);
}
#region ICustomFunctionOperator Members
public object Evaluate(params object[] operands) {
if(operands == null || operands.Length != 1) {
throw new ArgumentException();
}
object obj = operands[0];
IObjectSpace objectSpace = XPObjectSpace.FindObjectSpaceByObject(obj);
return objectSpace != null && objectSpace.IsNewObject(obj);
}
public string Name {
get { return OperatorName; }
}
public System.Type ResultType(params System.Type[] operands) {
return typeof(bool);
}
#endregion
}
}
Finally, the documentation on the new function is currently in works and it will be published with the nearest online help files update. I hope you find this little gem helpful. Please let us know in comments if you liked it as well as whether you plan to use this new function in other scenarios. I will be more than happy to hear from you.
P.S.
https://twitter.com/hashtag/dontkillseanbean;-)
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment