How to: Show a Custom Data-Bound Control in an XAF View (Blazor) - Current Object Data
- 3 minutes to read
This article explains how to create a reusable View Item that can work with data supplied by the View’s current object. Before you continue, make sure you are familiar with the tutorial that describes the commonly required steps - How to: Show a Custom Data-Bound Control in an XAF View (Blazor) - External Data.
Create a Razor Component
In this example, you create a Razor component based on DxAccordion. The new component displays employees assigned to a particular department.
To add this component to your project, follow the steps below:
- In the Solution Explorer, right-click your project’s name and select Add -> New Item from the ensuing context menu.
- Specify a component name (
DepartmentViewer.razor
). Add the following code to the created file.
@using MainDemo.Module.BusinessObjects; @using DevExpress.Blazor; @if (Department == null) { <div>No selected department.</div> } else { <p>Department name: <DxTextBox @bind-Text="@Department.Title" /></p> <p>Department head: @Department.DepartmentHead?.FullName</p> <p>Department description: @Department.Description</p> <DxAccordion ExpandMode="AccordionExpandMode.SingleOrNone" style="max-width: 600px" AnimationType="LayoutAnimationType.Slide"> <Items> @if(Department.Employees is not null) { @foreach(var employee in Department.Employees) { <DxAccordionItem Text="@employee.FullName" @key="employee"> <ContentTemplate> <div style="display: flex;"> <div style="flex: 1 0 0;"> <div><b>Full name:</b> @employee.FullName</div> <div><b>Email address:</b> @employee.Email</div> <div><b>Position:</b> @employee.Position</div> <div><b>Office:</b> @employee.Department.Office</div> @if(employee.Manager is not null) { <div><b>Manager:</b> @employee.Manager.FullName</div> } </div> <div style="flex: 1 0 0; display: flex; justify-content: end;"> @if(employee.Photo is not null) { <div style="flex: 1 0 0; display: flex; justify-content: end;"> <img src="@($"data:image/png;base64,{Convert.ToBase64String(employee.Photo)}")" style="max-width: 300px; max-height: 300px;"> </div> } </div> </div> </ContentTemplate> </DxAccordionItem> } } </Items> </DxAccordion> } @code { [Parameter] public Department Department { get; set; } }
The
DepartmentViewerModel.SetTitleFromUI
method notifies subscribers when a user changes the department’s title.In the Properties window, set this file’s
Build Action
toContent
.
Create a Custom View Item and its Control
Create a custom View Item that implements IComponentContentHolder
and returns DepartmentViewerModel
in the CreateControlCore
method. To do this, follow the steps below:
- Add a new file (
DepartmentViewerViewItem.cs
) to your Blazor project. Add the following code to the created file.
using DevExpress.ExpressApp.Blazor; using DevExpress.ExpressApp.Blazor.Components; using DevExpress.ExpressApp.Blazor.Components.Models; using DevExpress.ExpressApp.Editors; using DevExpress.ExpressApp.Model; using MainDemo.Blazor.Server.Controllers; using MainDemo.Module.BusinessObjects; using Microsoft.AspNetCore.Components; namespace MainDemo.Blazor.Server; public class DepartmentViewerModel : ComponentModelBase { public Department Department { get => GetPropertyValue<Department>(); set => SetPropertyValue(value); } public override Type ComponentType => typeof(DepartmentViewer); } public interface IModelDepartmentViewerViewItem : IModelViewItem { } [ViewItem(typeof(IModelDepartmentViewerViewItem))] public class DepartmentViewerViewItem : ViewItem, IComponentContentHolder { private RenderFragment _componentContent; public DepartmentViewerModel ComponentModel { get; private set; } public DepartmentViewerViewItem(IModelDepartmentViewerViewItem model, Type objectType) : base(objectType, model.Id) { } protected override object CreateControlCore() { ComponentModel = new DepartmentViewerModel { Department = View.CurrentObject as Department }; return ComponentModel; } public RenderFragment ComponentContent { get { _componentContent ??= ComponentModelObserver.Create(ComponentModel, ComponentModel.GetComponentContent()); return _componentContent; } } protected override void OnCurrentObjectChanged() { base.OnCurrentObjectChanged(); if(ComponentModel is not null) { ComponentModel.Department = View.CurrentObject as Department; } } }
Rebuild your solution.
For more information on how to implement View Items in XAF applications, refer to the following topic: Implement a View Item (WinForms).
Change the Default Detail View for the Department List View
In the Blazor application project, double-click the Model.xafml file to start the Model Editor. Right-click the Views node and choose Add | DetailView.
Set the Id property to CustomDepartment_DetailView and the ModelClass property to MainDemo.Module.BusinessObjects.Department.
Right-click the Views | MainDemo.Module.BusinessObjects | CustomDepartment_DetailView | Items node and choose Add… | DepartmentViewerItemView.
Set the Id property to DepartmentViewItem.
Navigate to the Views | MainDemo.Module.BusinessObjects | Department_ListView node. In the DetailView drop-down list, select CustomDepartment_DetailView.
Run the your Blazor application, navigate to the Department List View, open any Detail View, and see the result.