Solutions
To display a computed value from several business class properties (e.g., FullName, Email, Phone, etc.) in a lookup editor when it is in the closed state, use the XafDefaultProperty or LookupProperty attributes as shown in the code below:
Entity Framework Core
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.CompilerServices;
namespace SolutionName.Module.BusinessObjects {
[DefaultClassOptions]
[XafDefaultProperty("CustomerLookupDisplayText")]// Use this to set a lookup display property for a class globally.
public class Customer : BaseObject {
[NotMapped]
[Calculated("iif(IsNullOrEmpty(Email), CustomerName, concat(CustomerName, ' (', Email, ')'))")] // Use this for DataView access mode only.
public string CustomerLookupDisplayText {
get { return String.IsNullOrEmpty(Email) ? CustomerName : $"{CustomerName} ({Email})"; }
}
private string customerName;
public virtual string CustomerName {
get { return customerName; }
set { SetPropertyValue(ref customerName, value); }
}
private string email;
public virtual string Email {
get { return email; }
set { SetPropertyValue(ref email, value); }
}
}
[DefaultClassOptions]
public class Order : BaseObject {
private string name;
public virtual string Name {
get { return name; }
set { SetPropertyValue(ref name, value); }
}
private Customer customer;
[ModelDefault("LookupProperty", "CustomerLookupDisplayText")] // Use this to set a lookup display property for certain lookup properties only.
public virtual Customer Customer {
get { return customer; }
set { SetReferencePropertyValue(ref customer, value); }
}
}
public class BaseObject : INotifyPropertyChanged, IObjectSpaceLink, IXafEntityObject {
[Key]
[VisibleInDetailView(false), VisibleInListView(false), VisibleInLookupListView(false)]
public virtual Int32 ID { get; protected set; }
#region INotifyPropertyChanged
private PropertyChangedEventHandler propertyChanged;
protected bool SetPropertyValue<T>(ref T propertyValue, T newValue, [CallerMemberName] string propertyName = null) where T : struct {
if (EqualityComparer<T>.Default.Equals(propertyValue, newValue)) {
return false;
}
propertyValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
protected bool SetPropertyValue(ref string propertyValue, string newValue, [CallerMemberName] string propertyName = null) {
if (propertyValue == newValue) {
return false;
}
propertyValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
protected bool SetReferencePropertyValue<T>(ref T propertyValue, T newValue, [CallerMemberName] string propertyName = null) where T : class {
if (propertyValue == newValue) {
return false;
}
propertyValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged(string propertyName) {
if (propertyChanged != null) {
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged {
add { propertyChanged += value; }
remove { propertyChanged -= value; }
}
#endregion
#region IXafEntityObject members (see https://documentation.devexpress.com/eXpressAppFramework/clsDevExpressExpressAppIXafEntityObjecttopic.aspx)
public virtual void OnCreated() {
// Place the entity initialization code here.
// You can initialize reference properties using Object Space methods; e.g.:
// this.Address = objectSpace.CreateObject<Address>();
}
public virtual void OnLoaded() {
// Place the code that is executed each time the entity is loaded here.
}
public virtual void OnSaving() {
// Place the code that is executed each time the entity is saved here.
}
#endregion
#region IObjectSpaceLink members (see https://documentation.devexpress.com/eXpressAppFramework/clsDevExpressExpressAppIObjectSpaceLinktopic.aspx)
// Use the Object Space to access other entities from IXafEntityObject methods (see https://documentation.devexpress.com/eXpressAppFramework/CustomDocument113707.aspx).
[Browsable(false), NotMapped]
public IObjectSpace ObjectSpace { get; set; }
#endregion
}
}
XPO
C#using System;
using DevExpress.Xpo;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
namespace SolutionName.Module {
[DefaultClassOptions]
[XafDefaultProperty("CustomerLookupDisplayText")]// Use this to set a lookup display property for a class globally.
public class Customer : BaseObject {
public Customer(Session session) : base(session) { }
[PersistentAlias("iif(IsNullOrEmpty(Email), CustomerName, concat(CustomerName, ' (', Email, ')'))")]
public string CustomerLookupDisplayText {
get { return Convert.ToString(EvaluateAlias("CustomerLookupDisplayText")); }
}
private string customerName;
public string CustomerName {
get { return customerName; }
set { SetPropertyValue("CustomerName", ref customerName, value); }
}
private string email;
public string Email {
get { return email; }
set { SetPropertyValue("Email", ref email, value); }
}
}
[DefaultClassOptions]
public class Order : BaseObject {
public Order(Session session) : base(session) { }
private Customer customer;
[ModelDefault("LookupProperty", "CustomerLookupDisplayText")] // Use this to set a lookup display property for certain lookup properties only.
public Customer Customer {
get { return customer; }
set { SetPropertyValue("Customer", ref customer, value); }
}
}
}
Refer to the following articles to learn more about defining and making such calculated properties work for this UI customization:
- Customize Business Object's Metadata,
- Make a Property Calculable
- How to: Specify a Display Member (for a Lookup Editor, Detail Form Caption, etc.)
See Also
Allow Criteria Language Syntax in XafDefaultPropertyAttribute to enable complex non-persistent default properties without the need to create calculated properties
Core - Make it possible to modify the IModelClass.DefaultProperty via the Model Editor
Hi Dennis,
Any idea if or when this functionality will be available?
I need to add the icons of persistent objects (tatgettypes) to the closed ASPxLookupPropertyEditor, but couldn't find any examples/solutions!
This feature would be highly appreciated.
Kind regards,
Jos ter Doest
WiZZiX
While I cannot promise any time frame for this, I must say that it is already possible to implement this functionality in a custom Property Editor as described at http://documentation.devexpress.com/#Xaf/CustomDocument3097
Alternatively, you can customize the existing editor as shown at Access Editor Settings.
Our ASPxLookupPropertyEditor is based on our ASPxComboBox control, which you can customize in the ASPxLookupPropertyEditor descendant or in a ViewController.
To learn more on how to display a custom icon in the closed ASPxComboBox control, feel free to contact our ASP.NET team or check the related documentation on this control. To save your time, I have already created a separate ticket on your behalf: Q376912.
As for the WinForms, our LookupPropertyEditor is based on the PopupControlEdit component from our XtraEditors library, which can be customized to display an image as shown at PopupContainerEdit - Display Image.
Do not hesitate to contact the XAF team if you experience any difficulties integrating solutions for these components into your XAF app.
P.S.
In XAF you can use the ImageLoader class to get the information about class images.