PropertyComponent

PropertyComponent is the single Blazor component that renders the correct editor or viewer for any entity property. It reads the property's metadata from the server model, resolves the appropriate UI component, and wires up data binding and validation — all from a single Path parameter.

Basic Usage

<PropertyComponent Path="Id" />
<PropertyComponent Path="PrimaryContact.PrimaryEmail" />
<PropertyComponent Path="PrimaryContact.MailingAddress.Country" />

Each PropertyComponent must be inside a DataGraph, which provides the cascading DataGraphContext containing the DataSet, entity metadata, and display mode.

How Resolution Works

When PropertyComponent renders, it follows this resolution process:

  1. Exact match on (DataType, DisplayMode) — e.g., ("Email", Edit)
  2. Exact match on (Type, DisplayMode) — e.g., ("string", Edit)
  3. Fallback without DataGrid flag — e.g., Edit instead of DataGrid.Edit
  4. Fallback to base mode — Edit or View

If no component is found, PropertyComponent renders an error indicator.

Built-in Component Mappings

The following types are registered by default when you call AddCoreBlazor():

Scalar Types

Data Type / CLR Type Edit Component View Component
bool BooleanPropertyEdit — checkbox BooleanPropertyView — read-only checkbox
string StringPropertyEdit — text field StringPropertyView — plain text
int NumberPropertyEdit — numeric field NumberPropertyView — formatted number
decimal NumberPropertyEdit — numeric field NumberPropertyView — formatted number
double NumberPropertyEdit — numeric field NumberPropertyView — formatted number
Date DateOnlyPropertyEdit — date picker DateOnlyPropertyView — formatted date
DateTime DateTimePropertyEdit — date+time picker DateTimePropertyView — formatted date+time

Specialized String Types

These use StringPropertyEdit in edit mode but have specialized view components:

Data Type View Component Behavior
EmailAddress EmailPropertyView Renders as clickable mailto link
PhoneNumber PhonePropertyView Renders as clickable tel link
Url UrlPropertyView Renders as clickable hyperlink
FullAddress FullAddressPropertyView Multi-line formatted address

Enum Types

Any enum property resolves to these components. The server synthesizes DataType = "Enum" for enum properties and ships the member names in EnumValues (the dropdown's options) together with the corresponding numeric values in EnumUnderlyingValues. Values round-trip as the enum member name (a string).

Data Type Edit Component View Component
Enum EnumPropertyEdit — dropdown of enum members EnumPropertyView — selected member name
Data Type Edit Component View Component
Reference ReferencePropertyEdit — entity selector/autocomplete ReferencePropertyView — display text with optional link
Picker ReferencePropertyEditPicker — dropdown selector ReferencePropertyView
Collection CollectionPropertyEdit — editable data grid CollectionPropertyView — read-only table

PropertyComponent Parameters

Parameter Type Description
Path string (required) Property path in the DataSet (e.g., "PrimaryContact.PrimaryEmail")
ShowLabel bool? Override label visibility (null = auto based on display mode)
ShowColon bool? Show the label with a trailing colon ("Label:"); implies the label is shown. Default false.
DisplayMode DisplayMode? Override the display mode from the parent DataGraph
ChildContent RenderFragment<PropertyComponentContext> Custom component override

PropertyComponentContext

Every property component (built-in or custom) receives a PropertyComponentContext via cascading parameter. This context bundles the DataSet and the property's metadata:

Member Description
Get<T>() Read the current value from the DataSet
Set(value) Write a value (triggers DataSet.SetAsync asynchronously)
IsReadOnly() Whether the property is currently read-only (from server's RecordReadOnly)
GetShortMessage() First validation error/prompt for this property
GetLabel() Formatted label from metadata (e.g., "Primary Email")
IsDataGridDisplayMode() Whether we're rendering inside a collection grid

Custom Rendering with ChildContent

Override the default component for a specific property by providing ChildContent:

<PropertyComponent Path="PrimaryContact.Note">
    <MudTextField Value="@context.Get<string>()"
                  ValueChanged="@(value => context.Set(value))"
                  Label="@context.GetLabel()"
                  Lines="5"
                  Variant="Variant.Outlined" />
</PropertyComponent>

The context variable is a PropertyComponentContext — you can read/write values and access metadata through it. Use Value with ValueChanged to enable both read and write binding.

Reference Property Components

Reference properties (foreign keys to other entities) render as entity selectors:

@* Default: autocomplete search with server-side OData $search *@
<PropertyComponent Path="BillingCustomer" />

The ReferencePropertyEdit component:

  • Displays the referenced entity's title (or configured display property)
  • Provides autocomplete search against the server
  • Writes the selected entity's GUID back to the DataSet (BillingCustomerGuid)
  • Shows a lookup adornment to navigate to the referenced entity

Lookup Routes

The lookup adornment needs no LookUpUrl. ReferencePropertyEdit, ReferencePropertyEditPicker and ReferencePropertyView ask EntityPageRoutes for the page that opens one record of the referenced entity, which is the page carrying the route /{EntityName}/{key:guid}:

@page "/Customer/{CustomerGuid:guid}"

Give every entity page that route and every reference to it gets a lookup. An entity without one gets no lookup, so the adornment never points at a page that does not exist. Pass LookUpUrl only to send the lookup somewhere other than that page.

Customizing Reference Display

By default, references show the Title property. To customize, use ChildContent:

<PropertyComponent Path="BillingCustomer">
    <ReferencePropertyEdit DisplayProperty="Id" Clearable="true"
                           LookUpUrl="/customers" />
    </PropertyComponent>

Collection Property Components

Collection properties (one-to-many navigations) render as data grids:

<PropertyComponent Path="AdditionalContacts" />

CollectionPropertyEdit renders a table with:

  • One column per property in the navigation's graph definition
  • Inline editing via PropertyComponent for each cell
  • Add Row and Delete Row actions
  • Each row backed by a child IDataSet from DataSetCollection

Column Templates

Customize individual columns using ColumnTemplate:

<PropertyComponent Path="AdditionalContacts">
    <CollectionPropertyEdit>
        <ColumnTemplate Property="Role" Label="Contact Role">
            <ReferencePropertyEditPicker DisplayProperty="Name" />
        </ColumnTemplate>
    </CollectionPropertyEdit>
</PropertyComponent>

Row Actions

Add custom actions to each row:

<PropertyComponent Path="AdditionalContacts">
    <CollectionPropertyEdit>
        <CollectionRowAction Label="View Contact"
                             Icon="@Lucide.ExternalLink.Markup"
                             OnClick="@(item => NavigateToContact(item))" />
    </CollectionPropertyEdit>
</PropertyComponent>

Display Modes

PropertyComponent supports three display modes:

Mode Behavior
DisplayMode.Edit Renders interactive editors (text fields, pickers, checkboxes)
DisplayMode.View Renders read-only displays (text, links, formatted values)
DisplayMode.DataGrid Compact editors optimized for collection grid cells (no labels, smaller variant)

The display mode is set on DataGraph and cascaded to all children. Individual PropertyComponent instances can override it:

<DataGraph Builder="@BuildGraph" DataSet="@_dataSet" EntityGuid="@guid" DisplayMode="DisplayMode.Edit">
    <PropertyComponent Path="Id" />                              @* Edit mode *@
    <PropertyComponent Path="FullName" DisplayMode="DisplayMode.View" /> @* Forced View mode *@
</DataGraph>

Labels and the Colon

Two flags control the label on a View-mode label-before-value component (StringPropertyView, EmailPropertyView, ReferencePropertyView, …):

  • ShowLabel — shows the label as a plain word: Email alice@example.com.
  • ShowColon — shows the label with a trailing colon: Email: alice@example.com. Setting ShowColon implies the label is shown, so you don't also need ShowLabel. Default is false.
<PropertyComponent Path="Email" />                    @* value only (View mode hides labels by default) *@
<PropertyComponent Path="Email" ShowLabel="true" />   @* Email  alice@example.com *@
<PropertyComponent Path="Email" ShowColon="true" />   @* Email: alice@example.com *@

The colon is presentation added by the component, never part of the model label, and it applies only to label-before-value View components — edit-mode floating field labels, data-grid headers, and BooleanPropertyView stay colon-free regardless of ShowColon.

Labels themselves come from the model: the property's Label, falling back to the humanized property name (AccountNumber → Account Number). If the displayed wording is wrong, change the model label rather than overriding it on the client. For a full read-only "Label: value" list, use GroupLayout.Detail.

Change Handling

PropertyComponent subscribes to DataSet.Changed events internally. When a change affects its path, it re-renders automatically. You don't need to wire up change handling for individual properties — it happens behind the scenes.

The re-render is targeted: only properties affected by the change update. This is efficient even on pages with many properties.

MethodButton

MethodButton turns a server [Method] into a button driven by graph metadata — it shows the provided Label (or the method name), hides when the user lacks permission, and greys out when the server disables it.

<MethodButton Method="ApplySurcharge" DataSet="@dataSet" Label="Apply surcharge" />

See Method Buttons for the full pipeline, auto-invoke vs manual modes, and custom content.

See Property Groups for group layout, nested groups, and inline property or group overrides.

Shared Editor Behaviors

These behaviors ship with the built-in editors, so pages get them without extra wiring:

  • Clear buttons. StringPropertyEdit and NumberPropertyEdit render a clear button outside grid cells. Clearing a number writes null; clearing a string writes "" (OData rejects null outright for a required string). CoreEntitySelector's clear button is hidden until the field is hovered or focused.
  • Format override. <NumberPropertyEdit Format="N3" Step="0.01m" /> overrides the metadata format when the precision is only known at runtime.
  • Enum labels. Display text is humanized ("PartiallyFulfilled" → "Partially Fulfilled") via LabelFormatter.FormatLabel; the bound value stays the raw member name. LabelFormatter.FormatPropertyLabel(PropertyMetaData) returns the declared label, else the humanized property name.
  • Row actions menu. CoreActionsMenu is the shared three-dot menu: one icon and one neutral color everywhere. Screens style the popover content, never the trigger.
  • Ctrl+Enter adds a row. Collection grids register with KeyboardEventService (RegisterAddRow/SyncAddRow); the focused grid wins, otherwise the most recently registered visible grid. Hidden tab panels are excluded. The shortcut is ignored while typing in an editor outside a grid.