xaf-conditional-appearance
XAF: Conditional Appearance
Overview
Conditional Appearance controls UI elements dynamically based on business rules: visibility, enabled state, colors, font style, and custom CSS — all without writing controller code for simple cases.
Setup
// In Module:
public class MyModule : ModuleBase {
public MyModule() {
RequiredModuleTypes.Add(typeof(ConditionalAppearanceModule));
}
}
// Or in Program.cs:
b.AddModule<ConditionalAppearanceModule>();
[Appearance] Attribute — All Parameters
[Appearance(
"RuleId", // unique rule identifier (required)
Criteria = "Status = 'Cancelled'", // XAF criteria expression (required)
TargetItems = "CancellationReason", // property name(s), "*" = all, ";" = multiple
Context = "DetailView", // "Any", "DetailView", "ListView", or custom
AppearanceItemType = "ViewItem", // "ViewItem", "Action", "LayoutItem"
Visibility = ViewItemVisibility.Show, // Show, Hide, ShowEmptySpace
Enabled = false, // true/false
FontColor = "Red", // named color or hex (#FF0000)
BackColor = "LightYellow", // background color
FontStyle = FontStyle.Bold, // Bold, Italic, Strikeout, Underline
Priority = 0 // higher priority wins when multiple rules apply
)]
Apply to a class to affect properties within it:
[Appearance("Rule", Criteria = "...", TargetItems = "PropertyName")]
public class Order : BaseObject { ... }
Apply to a property itself (targets that property):
public class Order : BaseObject {
[Appearance("RequiredWhenActive", Criteria = "Status = 'Active'",
FontColor = "Red")]
public virtual string ResponsiblePerson { get; set; }
}
Common Patterns
Hide field based on enum value
[Appearance("HideCancellationReason",
Criteria = "Status != 'Cancelled'",
TargetItems = "CancellationReason",
Visibility = ViewItemVisibility.Hide)]
[Appearance("ShowCancellationReason",
Criteria = "Status = 'Cancelled'",
TargetItems = "CancellationReason",
Visibility = ViewItemVisibility.Show)]
public class Order : BaseObject {
public virtual OrderStatus Status { get; set; }
public virtual string CancellationReason { get; set; }
}
Disable field based on boolean
[Appearance("LockWhenApproved",
Criteria = "IsApproved = true",
TargetItems = "Amount;Description;Category",
Enabled = false)]
public class Invoice : BaseObject {
public virtual bool IsApproved { get; set; }
public virtual decimal Amount { get; set; }
public virtual string Description { get; set; }
public virtual Category Category { get; set; }
}
Color list view row based on status
[Appearance("OverdueRow",
Criteria = "DueDate < LocalDateTimeToday() AND Status != 'Completed'",
Context = "Any",
AppearanceItemType = "DataRow",
BackColor = "#FFEEEE",
FontColor = "DarkRed")]
public class Task : BaseObject {
public virtual DateTime DueDate { get; set; }
public virtual TaskStatus Status { get; set; }
}
Hide action based on condition
[Appearance("HideDeleteWhenLocked",
Criteria = "IsLocked = true",
AppearanceItemType = "Action",
TargetItems = "DeleteAction",
Visibility = ViewItemVisibility.Hide)]
public class Contract : BaseObject {
public virtual bool IsLocked { get; set; }
}
Custom CSS class in Blazor
[Appearance("HighlightPremium",
Criteria = "IsPremium = true",
Context = "DetailView",
CssClass = "premium-highlight")]
public class Customer : BaseObject {
public virtual bool IsPremium { get; set; }
}
Criteria Expression Syntax
| Operator | Example |
|---|---|
| Equals | Status = 'Active' |
| Not equals | Status != 'Cancelled' |
| Comparison | Amount > 1000 |
| AND / OR / NOT | Active = true AND Amount > 0 |
| IsNull | IsNull([Manager]) |
| IsNullOrEmpty | IsNullOrEmpty([Email]) |
| Contains | Contains([Name], 'Smith') |
| StartsWith | StartsWith([Code], 'ORD') |
| Date functions | DueDate < LocalDateTimeToday() |
| CurrentUser | Owner.UserName = CurrentUserId() |
| Enum | Status = ##Enum#MyNamespace.Status,Active## |
Targeting Multiple Properties
// Multiple properties: separate with semicolon
TargetItems = "FirstName;LastName;Email"
// All properties
TargetItems = "*"
// All properties except exclusions: no direct support
// Use separate rules with Priority to handle order
Multiple Appearance Rules (Priority)
[Appearance("Rule1", Criteria = "Amount > 1000", BackColor = "LightGreen", Priority = 1)]
[Appearance("Rule2", Criteria = "Amount > 5000", BackColor = "Gold", Priority = 2)]
public virtual decimal Amount { get; set; }
// Higher Priority wins when multiple criteria are true
Dynamic Appearance from Code
Using IAppearanceEnabled / IAppearanceVisibility
public class OrderViewController : ObjectViewController<DetailView, Order> {
protected override void OnActivated() {
base.OnActivated();
View.CurrentObjectChanged += UpdateAppearance;
UpdateAppearance(null, null);
}
protected override void OnDeactivated() {
View.CurrentObjectChanged -= UpdateAppearance;
base.OnDeactivated();
}
private void UpdateAppearance(object sender, EventArgs e) {
if (View.CurrentObject is not Order order) return;
// Find view items and change appearance programmatically
var amountItem = View.FindItem("Amount") as IAppearanceEnabled;
if (amountItem != null)
amountItem.Enabled = !order.IsLocked;
var cancelReasonItem = View.FindItem("CancellationReason") as IAppearanceVisibility;
if (cancelReasonItem != null)
cancelReasonItem.Visibility = order.Status == OrderStatus.Cancelled
? ViewItemVisibility.Show
: ViewItemVisibility.Hide;
}
}
Model-Based Rules (Application Model)
Define rules in the Application Model (Model Editor) without code changes:
Path: Views > <ClassName>_DetailView > AppearanceRules
Add AppearanceRule node with:
Criteria— condition expressionTargetItems— property namesVisibility,Enabled,FontColor,BackColor,FontStyle
Useful for rules that business users need to modify without code deployment.
AppearanceItemType Values
| Value | Targets |
|---|---|
ViewItem |
Property editor (field) |
DataRow |
Entire list view row |
Action |
Action button |
LayoutItem |
Layout group or tab |
Source Links
- Conditional Appearance: https://docs.devexpress.com/eXpressAppFramework/113286/conditional-appearance
- AppearanceAttribute: https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ConditionalAppearance.AppearanceAttribute
- IAppearanceEnabled: https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ConditionalAppearance.IAppearanceEnabled
- IAppearanceVisibility: https://docs.devexpress.com/eXpressAppFramework/DevExpress.ExpressApp.ConditionalAppearance.IAppearanceVisibility
- Criteria Expression Syntax: https://docs.devexpress.com/CoreLibraries/4928/devexpress-data-library/criteria-language-syntax
More from kashiash/xaf-skills
xaf
DevExpress XAF (eXpressApp Framework) master index. Use this skill first when working with any XAF topic to find the right sub-skill. Covers Blazor and WinForms, EF Core and XPO, versions v24.2 and v25.1. Sub-skills: xaf-xpo-models, xaf-ef-models, xaf-controllers, xaf-editors, xaf-custom-editors, xaf-nonpersistent, xaf-security, xaf-multi-tenant, xaf-web-api, xaf-validation, xaf-reports, xaf-dashboards, xaf-office, xaf-blazor-ui, xaf-winforms-ui, xaf-conditional-appearance, xaf-deployment, xaf-memory-leaks.
13xaf-winforms-ui
XAF WinForms UI platform - WinApplication setup, Ribbon vs Standard toolbar, WinForms-specific editors (XtraGrid, DevExpress controls), Detail View layout customization via Layout Manager, custom WinForms controls embedded in XAF views, background workers for thread-safe UI updates, splash screen customization, WinForms navigation (NavigationFrame), printing/preview in WinForms, ClickOnce/MSI deployment. Use when building or customizing XAF WinForms applications.
10xaf-blazor-ui
XAF Blazor UI platform - BlazorApplication setup in Program.cs, AddXaf/AddXafBlazor services, InvokeAsync thread safety (critical for Blazor Server), async controller actions pattern, Blazor-specific editors, embedding custom Razor components as ViewItems using IComponentContentHolder, JavaScript interop via IJSRuntime, Detail View layout customization (tabs/groups), programmatic navigation, error handling with UserFriendlyException, SignalR configuration. Use when building or customizing XAF Blazor Server applications.
10xaf-office
XAF Office/Document Management Modules - FileAttachmentsModule with IFileData/FileAttachment patterns (XPO and EF Core), SpreadsheetModule for Excel editing with ISpreadsheetValueStorage, RichTextModule for Word-like editing with IRichTextDocumentProvider and mail merge, PdfViewerModule for PDF display, platform differences (Blazor vs WinForms), programmatic document manipulation. Use when adding file attachments, spreadsheet editing, rich text editing, or PDF viewing to DevExpress XAF applications.
9xaf-reports
XAF Reports Module (XtraReports v2) - ReportsModuleV2 setup for Blazor and WinForms, report storage (DB/filesystem/custom IReportStorageWebExtension), creating predefined reports in code (PredefinedReportsUpdater), data sources (CollectionDataSource/EntityServerModeSource), report parameters, programmatic export (PDF/Excel/Word), in-app designer, PrintAction, security permissions for report design vs view. Use when working with DevExpress XtraReports integration in XAF.
9xaf-editors
XAF built-in property editors and list editors - editor type mapping by data type, EditorAliases constants, [EditorAlias] attribute, [ModelDefault] for DisplayFormat/EditMask, ObjectPropertyEditor for inline sub-forms, list editor types (GridListEditor, DxGridListEditor, TreeListEditor, ChartListEditor), GridListEditor WinForms customization, DxGridListEditor Blazor customization, IModelListView/IModelColumn properties. Use when working with built-in XAF editors or customizing grid/list views.
8