Blazorise PropertyGrid component
Display and edit related values in a compact inspector with grouping, sorting, search, and contextual help.
Overview
A property grid presents a large set of editable values without the space and visual weight of a conventional form. It is well suited to designer surfaces, object inspectors, settings panels, and other interfaces where users need to review and adjust many related options.
Each property is displayed as a label and editor row, with related properties organized into collapsible groups. Properties can be searched or arranged by category or name, while optional row actions and descriptions provide additional behavior and guidance without crowding the editor.
Structure
<PropertyGrid>is the main container for a manually composed property grid.<PropertyGridToolbar>is the container for commands and search controls.<PropertyGridToolbarButton>is a toolbar command, such as switching the property view mode.<PropertyGridToolbarSearch>is a search input that captures property filter text.
<PropertyGridGroup>is an expandable group of related property rows.<PropertyGridItem>is a property row with a label, editor content, and optional action.<PropertyGridTextItem>,<PropertyGridBooleanItem>,PropertyGridNumericItem<TValue>,PropertyGridSelectItem<TValue>,<PropertyGridStringSelectItem>, and<PropertyGridColorItem>are ready-to-use property rows for common value types.
<PropertyGridHelp>is the panel that displays the selected property's name and description.
<PropertyGridView>is a higher-level component that builds the toolbar, groups, rows, and help panel from aPropertyGridSchema.
Choosing an approach
Use <PropertyGrid> for a fixed set of properties known in Razor markup.
Compose its toolbar, groups, editors, and help panel directly, and bind each editor to the corresponding value.
This approach gives you full control over which components are rendered and how filtering is applied.
Use <PropertyGridView> when properties are dynamic or supplied by application metadata.
A PropertyGridSchema describes the groups, editor types, values, descriptions, and actions, while the view builds the complete property grid.
Handle PropertyValueChanged using the stable property key, update the backing model, and provide a new schema when displayed values change.
Give either component a constrained Height to keep large property sets inside an independently scrolling viewport.
The toolbar remains visible while properties scroll, and selecting a property shows its Description in the help panel.
Property groups and rows include the grid, selection, and expansion semantics needed by assistive technologies.
Examples
Basic
Use manual composition when the available properties are known in advance. This example binds editor components directly, supplies a complete reset button throughActionContent, adds search in the toolbar, and filters the rendered rows in Razor.
Current values: Quarterly summary, 640 x 360 px, Arial 16 px, Left, Blue, visible
<PropertyGrid Width="Width.Px( 360 )"> <Toolbar> <PropertyGridToolbar> <PropertyGridToolbarButton Icon="IconName.Clear" Title="Clear search" Disabled="@( string.IsNullOrWhiteSpace( searchText ) )" Clicked="" /> <PropertyGridToolbarSearch @bind-SearchText="" /> </PropertyGridToolbar> </Toolbar> <ChildContent> <PropertyGridGroup Title="Appearance"> @if ( MatchesSearch( "Title" ) ) { <PropertyGridTextItem Label="Title" @bind-Value=""> <ActionContent> <Button Color="Color.Light" Size="Size.Small" Clicked="" title="Reset title" aria-label="Reset title"> <Icon Name="IconName.Undo" /> </Button> </ActionContent> </PropertyGridTextItem> } @if ( MatchesSearch( "Visible" ) ) { <PropertyGridBooleanItem Label="Visible" @bind-Value="" TrueText="Visible" FalseText="Hidden" /> } @if ( MatchesSearch( "Accent" ) ) { <PropertyGridColorItem Label="Accent" @bind-Value="" /> } </PropertyGridGroup> <PropertyGridGroup Title="Typography"> @if ( MatchesSearch( "Font family" ) ) { <PropertyGridStringSelectItem Label="Font family" @bind-Value="" Options="" /> } @if ( MatchesSearch( "Font size" ) ) { <PropertyGridNumericItem TValue="int" Label="Font size" @bind-Value="" Min="8" Max="72" /> } @if ( MatchesSearch( "Bold" ) ) { <PropertyGridBooleanItem Label="Bold" @bind-Value="" /> } @if ( MatchesSearch( "Italic" ) ) { <PropertyGridBooleanItem Label="Italic" @bind-Value="" /> } </PropertyGridGroup> <PropertyGridGroup Title="Layout"> @if ( MatchesSearch( "Width" ) ) { <PropertyGridNumericItem TValue="int" Label="Width" @bind-Value="" Min="100" Max="1200" Step="10" /> } @if ( MatchesSearch( "Height" ) ) { <PropertyGridNumericItem TValue="int" Label="Height" @bind-Value="" Min="100" Max="1200" Step="10" /> } @if ( MatchesSearch( "Padding" ) ) { <PropertyGridNumericItem TValue="int" Label="Padding" @bind-Value="" Min="0" Max="64" /> } @if ( MatchesSearch( "Alignment" ) ) { <PropertyGridStringSelectItem Label="Alignment" @bind-Value="" Options="" /> } </PropertyGridGroup> </ChildContent> <Help> <PropertyGridHelp Title="Manual composition" Description="Toolbar, editor, filtering, and help behavior can be composed directly." /> </Help> </PropertyGrid> <Paragraph Margin="Margin.Is3.FromTop"> <Strong>Current values:</Strong> @title, @width x @height px, @fontFamily @fontSize px, @alignment, @accent, @(visible ? "visible" : "hidden") </Paragraph>
@code { private static readonly IReadOnlyList<PropertyGridSelectOption<string>> alignmentOptions = [ new( "Left", "Left" ), new( "Center", "Center" ), new( "Right", "Right" ), ]; private static readonly IReadOnlyList<PropertyGridSelectOption<string>> fontFamilyOptions = [ new( "Arial", "Arial" ), new( "Georgia", "Georgia" ), new( "Inter", "Inter" ), ]; private string title = "Quarterly summary"; private bool visible = true; private string accent = "Blue"; private string fontFamily = "Arial"; private int fontSize = 16; private bool bold; private bool italic; private int width = 640; private int height = 360; private int padding = 16; private string alignment = "Left"; private string searchText; private bool MatchesSearch( string label ) => string.IsNullOrWhiteSpace( searchText ) || label.Contains( searchText, StringComparison.CurrentCultureIgnoreCase ); private void ClearSearch() => searchText = string.Empty; private void ResetTitle() => title = "Quarterly summary"; }
Schema
Use a schema for property sets created at runtime.<PropertyGridView> renders the appropriate editors and reports changes by property key so the backing model can be updated.
Status: Change a property or invoke its action.
<PropertyGridView Width="Width.Px( 360 )" Schema="" PropertyValueChanged="" ActionInvoked="" @bind-SelectedProperty="" @bind-ViewMode="" /> <Paragraph Margin="Margin.Is3.FromTop"> <Strong>Status:</Strong> @status @if ( selectedProperty is not null ) { <Span> Selected: @selectedProperty.Label.</Span> } </Paragraph>
@code { private string documentName = "Quarterly report"; private string documentDescription = "Quarterly financial performance."; private string category = "Finance"; private bool enabled = true; private int pageWidth = 794; private int pageHeight = 1123; private string orientation = "Portrait"; private int copies = 1; private string format = "PDF"; private string accent = "Blue"; private bool includePageNumbers = true; private string status = "Change a property or invoke its action."; private PropertyGridViewMode viewMode = PropertyGridViewMode.Categorized; private PropertyGridSchema schema; private PropertyGridProperty selectedProperty; protected override void OnInitialized() { schema = BuildSchema(); } private PropertyGridSchema BuildSchema() => new( [ new PropertyGridGroupDefinition( "document", "Document", [ new PropertyGridTextProperty( "document.name", "Name", documentName ) { Description = "The display name used for the generated document.", Immediate = true, Action = new PropertyGridAction( "rename" ) { Icon = IconName.Edit, Title = "Rename document", }, }, new PropertyGridBooleanProperty( "document.enabled", "Enabled", enabled ) { Description = "Controls whether the document is included in output.", TrueText = "Enabled", FalseText = "Disabled", }, new PropertyGridTextProperty( "document.description", "Description", documentDescription ) { Description = "A short summary of the document contents.", Immediate = true, }, new PropertyGridStringSelectProperty( "document.category", "Category", category, [ new( "Finance", "Finance" ), new( "Operations", "Operations" ), new( "Sales", "Sales" ), ] ) { Description = "The category used to organize the document.", }, ] ), new PropertyGridGroupDefinition( "layout", "Layout", [ new PropertyGridNumericProperty<int>( "layout.width", "Page width", pageWidth ) { Description = "The page width in pixels.", Min = 100, Max = 2000, }, new PropertyGridNumericProperty<int>( "layout.height", "Page height", pageHeight ) { Description = "The page height in pixels.", Min = 100, Max = 2000, }, new PropertyGridStringSelectProperty( "layout.orientation", "Orientation", orientation, [ new( "Portrait", "Portrait" ), new( "Landscape", "Landscape" ), ] ) { Description = "The page orientation used during export.", }, ] ), new PropertyGridGroupDefinition( "output", "Output", [ new PropertyGridStringSelectProperty( "output.format", "Format", format, [ new( "PDF", "PDF" ), new( "HTML", "HTML" ), new( "CSV", "CSV" ), ] ) { Description = "The file format used when the document is exported.", }, new PropertyGridNumericProperty<int>( "output.copies", "Copies", copies ) { Description = "The number of output copies to create.", Min = 1, Max = 10, }, new PropertyGridColorProperty( "output.accent", "Accent", accent ) { Description = "The accent color used by the document theme.", }, new PropertyGridBooleanProperty( "output.pageNumbers", "Page numbers", includePageNumbers ) { Description = "Controls whether page numbers are included in output.", TrueText = "Included", FalseText = "Hidden", }, ] ), ] ); private void OnPropertyValueChanged( PropertyGridValueChangedEventArgs eventArgs ) { switch ( eventArgs.PropertyKey ) { case "document.name": documentName = eventArgs.GetValue<string>(); break; case "document.enabled": enabled = eventArgs.GetValue<bool>(); break; case "document.description": documentDescription = eventArgs.GetValue<string>(); break; case "document.category": category = eventArgs.GetValue<string>(); break; case "layout.width": pageWidth = eventArgs.GetValue<int>(); break; case "layout.height": pageHeight = eventArgs.GetValue<int>(); break; case "layout.orientation": orientation = eventArgs.GetValue<string>(); break; case "output.format": format = eventArgs.GetValue<string>(); break; case "output.copies": copies = eventArgs.GetValue<int>(); break; case "output.accent": accent = eventArgs.GetValue<string>(); break; case "output.pageNumbers": includePageNumbers = eventArgs.GetValue<bool>(); break; } status = $"{eventArgs.Property.Label} changed."; schema = BuildSchema(); } private void OnActionInvoked( PropertyGridActionEventArgs eventArgs ) { status = $"{eventArgs.Action.Name} invoked for {eventArgs.Property.Label}."; } }
Templates
Keep the schema-driven behavior while replacing selected parts of the UI. Templates can customize the toolbar, groups, rows, labels, editors, and actions, and their contexts provide the current definition and update callbacks.Current item: Revenue, Card, 100% opacity
<PropertyGridView Width="Width.Px( 360 )" Schema="" PropertyValueChanged="" ActionInvoked="" ShowToolbar="false"> <GroupHeaderTemplate Context="context"> <Span Display="Display.Flex" Flex="Flex.AlignItems.Center" Gap="Gap.Is2"> <Icon Name="IconName.Wrench" /> <Strong>@context.Group.Title</Strong> </Span> </GroupHeaderTemplate> <LabelTemplate Context="context"> <Strong>@context.Label</Strong> </LabelTemplate> <TextEditorTemplate Context="context"> <TextInput Value="@( context.GetValue<string>() )" ValueChanged="@( ( string value ) => context.SetValue( value ) )" Size="Size.Small" /> </TextEditorTemplate> <ActionTemplate Context="context"> <Button Color="Color.Warning" Size="Size.Small" Title="@context.Action.Title" Clicked="@context.Invoke"> @context.Action.Text </Button> </ActionTemplate> <HelpTemplate Context="context"> <Strong>About @context.Label</Strong> <Text>@context.Description</Text> </HelpTemplate> </PropertyGridView> <Paragraph Margin="Margin.Is3.FromTop"> <Strong>Current item:</Strong> @displayName, @layoutMode, @opacity% opacity </Paragraph>
@code { private string displayName = "Revenue"; private string subtitle = "Year-to-date"; private bool highlighted = true; private bool visible = true; private string accent = "Blue"; private int opacity = 100; private string layoutMode = "Card"; private bool locked; private string notes = "Reviewed monthly."; private PropertyGridSchema schema; protected override void OnInitialized() { schema = BuildSchema(); } private PropertyGridSchema BuildSchema() => new( [ new PropertyGridGroupDefinition( "appearance", "Custom appearance", [ new PropertyGridTextProperty( "appearance.name", "Display name", displayName ) { Description = "The name displayed to users.", Immediate = true, Action = new PropertyGridAction( "reset" ) { Text = "Reset", Title = "Reset display name", }, }, new PropertyGridBooleanProperty( "appearance.highlighted", "Highlighted", highlighted ) { Description = "Emphasizes the item in the rendered output.", }, new PropertyGridTextProperty( "appearance.subtitle", "Subtitle", subtitle ) { Description = "The supporting text displayed below the name.", Immediate = true, }, new PropertyGridBooleanProperty( "appearance.visible", "Visible", visible ) { Description = "Controls whether the item is displayed.", }, new PropertyGridColorProperty( "appearance.accent", "Accent", accent ) { Description = "The accent color used to emphasize the item.", }, new PropertyGridNumericProperty<int>( "appearance.opacity", "Opacity", opacity ) { Description = "The item opacity as a percentage.", Min = 0, Max = 100, }, ] ), new PropertyGridGroupDefinition( "behavior", "Custom behavior", [ new PropertyGridStringSelectProperty( "behavior.layout", "Layout", layoutMode, [ new( "Card", "Card" ), new( "Compact", "Compact" ), new( "Expanded", "Expanded" ), ] ) { Description = "The layout used to present the item.", }, new PropertyGridBooleanProperty( "behavior.locked", "Locked", locked ) { Description = "Prevents the item from being repositioned.", }, new PropertyGridTextProperty( "behavior.notes", "Notes", notes ) { Description = "Additional information about the item.", Immediate = true, }, ] ), ] ); private void OnPropertyValueChanged( PropertyGridValueChangedEventArgs eventArgs ) { switch ( eventArgs.PropertyKey ) { case "appearance.name": displayName = eventArgs.GetValue<string>(); break; case "appearance.subtitle": subtitle = eventArgs.GetValue<string>(); break; case "appearance.highlighted": highlighted = eventArgs.GetValue<bool>(); break; case "appearance.visible": visible = eventArgs.GetValue<bool>(); break; case "appearance.accent": accent = eventArgs.GetValue<string>(); break; case "appearance.opacity": opacity = eventArgs.GetValue<int>(); break; case "behavior.layout": layoutMode = eventArgs.GetValue<string>(); break; case "behavior.locked": locked = eventArgs.GetValue<bool>(); break; case "behavior.notes": notes = eventArgs.GetValue<string>(); break; } schema = BuildSchema(); } private void OnActionInvoked( PropertyGridActionEventArgs eventArgs ) { if ( eventArgs.Action.Name != "reset" ) return; displayName = "Revenue"; schema = BuildSchema(); } }
API
Parameters
PropertyGrid
| Parameter | Description | Type | Default |
|---|---|---|---|
AriaLabel |
Defines the accessible property grid label. |
string | "Properties" |
ChildContent |
Specifies the property groups to be rendered inside this PropertyGrid. |
RenderFragment | null |
Help |
Specifies content rendered below the scrollable property viewport. |
RenderFragment | null |
Toolbar |
Specifies content rendered above the scrollable property viewport. |
RenderFragment | null |
PropertyGridView
| Parameter | Description | Type | Default |
|---|---|---|---|
ActionTemplate |
Defines an action template. |
RenderFragment<PropertyGridActionContext> | null |
AlphabeticalButtonIcon |
Gets or sets the alphabetical button icon. |
IconName | IconName.SortAlphaDown |
AlphabeticalButtonTemplate |
Defines the alphabetical view button template. |
RenderFragment<PropertyGridViewModeContext> | null |
AlphabeticalButtonTitle |
Gets or sets the alphabetical button title. |
string | "Alphabetical" |
AriaLabel |
Gets or sets the accessible property grid label. |
string | "Properties" |
BooleanEditorTemplate |
Defines a boolean editor template. |
RenderFragment<PropertyGridEditorContext> | null |
CategorizedButtonIcon |
Gets or sets the categorized button icon. |
IconName | IconName.List |
CategorizedButtonTemplate |
Defines the categorized view button template. |
RenderFragment<PropertyGridViewModeContext> | null |
CategorizedButtonTitle |
Gets or sets the categorized button title. |
string | "Categorized" |
ChildContent |
Defines content rendered after all schema groups. |
RenderFragment | null |
ColorEditorTemplate |
Defines a color editor template. |
RenderFragment<PropertyGridEditorContext> | null |
EmptyTemplate |
Defines content rendered when the schema and child content are empty. |
RenderFragment | null |
GroupHeaderTemplate |
Defines a group header template. |
RenderFragment<PropertyGridGroupContext> | null |
GroupTemplate |
Defines a complete group template. |
RenderFragment<PropertyGridGroupContext> | null |
HelpTemplate |
Defines the selected property help template. |
RenderFragment<PropertyGridHelpContext> | null |
ItemTemplate |
Defines a complete property item template. |
RenderFragment<PropertyGridItemContext> | null |
LabelTemplate |
Defines a property label template. |
RenderFragment<PropertyGridLabelContext> | null |
NoResultsTemplate |
Defines content rendered when no properties match the current search. |
RenderFragment | null |
NoResultsText |
Defines the text rendered when no properties match the current search. |
string | "No properties found." |
NumericEditorTemplate |
Defines a numeric editor template. |
RenderFragment<PropertyGridEditorContext> | null |
Schema |
Gets or sets the schema rendered by the property grid. |
PropertyGridSchema | null |
SearchAriaLabel |
Gets or sets the accessible property search label. |
string | "Search properties" |
SearchDebounce |
Gets or sets whether property search changes are debounced. |
bool | true |
SearchDebounceInterval |
Gets or sets the property search debounce interval in milliseconds. |
int | 300 |
SearchPlaceholder |
Gets or sets the property search placeholder. |
string | "Search" |
SearchTemplate |
Defines the property search template. |
RenderFragment<PropertyGridSearchContext> | null |
SearchText |
Gets or sets the property search text. |
string | |
SelectEditorTemplate |
Defines a select editor template. |
RenderFragment<PropertyGridEditorContext> | null |
SelectedProperty |
Gets or sets the selected property. |
PropertyGridProperty | null |
ShowHelp |
Gets or sets whether help for the selected property is shown. |
bool | true |
ShowSearch |
Gets or sets whether the property search editor is shown. |
bool | true |
ShowToolbar |
Gets or sets whether the property grid toolbar is shown. |
bool | true |
ShowViewModeButtons |
Gets or sets whether the categorized and alphabetical view buttons are shown. |
bool | true |
TextEditorTemplate |
Defines a text editor template. |
RenderFragment<PropertyGridEditorContext> | null |
ToolbarAriaLabel |
Gets or sets the accessible property grid toolbar label. |
string | "Property grid controls" |
ToolbarTemplate |
Defines the complete toolbar template. |
RenderFragment<PropertyGridToolbarContext> | null |
ViewMode |
Gets or sets how properties are arranged. Possible values: |
PropertyGridViewMode | PropertyGridViewMode.Categorized |
Events
PropertyGridView
| Event | Description | Type |
|---|---|---|
ActionInvoked |
Occurs after a property action is invoked. |
EventCallback<PropertyGridActionEventArgs> |
GroupExpandedChanged |
Occurs after a property group expansion state changes. |
EventCallback<PropertyGridGroupExpandedEventArgs> |
PropertyValueChanged |
Occurs after a property value changes. |
EventCallback<PropertyGridValueChangedEventArgs> |
SearchTextChanged |
Occurs after the property search text changes. |
EventCallback<string> |
SelectedPropertyChanged |
Occurs after the selected property changes. |
EventCallback<PropertyGridProperty> |
ViewModeChanged |
Occurs after the property arrangement changes. |
EventCallback<PropertyGridViewMode> |