Skip to content

Integrate the TreeList editor to your XAF ASP.NET Core Blazor application.

License

Notifications You must be signed in to change notification settings

DevExpress-Examples/xaf-treelist-editor-blazor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

XAF Blazor - How to Implement a TreeList Editor to Display Hierarchical Data

Note
We created this example only for demonstration purposes. We can't guarantee that it will work in all usage scenarios. If you need to add some functionality to it, feel free to do this on your own. Researching DevExpress source code will help you with this task. Also, refer to the following help topic for more information: Debug DevExpress .NET Source Code with Debug Symbols. Unfortunately extending this example with custom code is outside the scope of our Support Service: Technical Support Scope.

Implement the following components to add the TreeList Editor to your ASP.NET Core Blazor application:

  • A Razor component based on the DevExtreme TreeList widget.
  • A component model that changes the state of the component.
  • A component renderer that binds the component model with the component.
  • A List Editor that integrates the component into your XAF application.

The following image demonstrates the result:

example

Alternative Solutions

Group List View Data Using DxGridListEditor

If this DevExtreme-based solution does not meet your requirements (for instance, you do not want to implement the ITreeNode contract in your data model from scratch or do not want to inherit your class from our HCategory), you can consider using the data grid and group by the 'Parent' property to emulate a tree: Group List View Data. In this case, it is also natural to enable a 'Split View' (MasterDetailMode = ListAndDetailView): Enable Split Layout in a List View.

Implement a Custom List Editor or View Item from Scratch

Of course, you can also build your own List Editor or View Item to display your custom data model using suitable DevExtreme or Blazor components: Using a Custom Control that is not Integrated by Default.

Implementation Details

ITreeNode-based Data Model

XAF has a built-in ITreeNode interface, which can be implemented by business objects to visualize them as a tree in a ListView (refer to the Category and related classes in this example). You can find more example code of ITreeNode-based data models below OR you can inherit your business class from our built-in HCategory class):

  • EF Core: "c:\Program Files\DevExpress 2X.Y\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.EFCore\HCategory.cs"
  • XPO: "c:\Program Files\DevExpress 2X.Y\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.Xpo\HCategory.cs"

This hierarchical data visualization is currently supported for WinForms and ASP.NET WebForms out-of-the-box (hence this example for ASP.NET Core Blazor).

Razor Component

  1. Create a Razor class library (RCL) project (BlazorComponents). Reference it in your TreeListDemoEF.Blazor.Server project.

  2. Register DevExtreme libraries in the TreeListDemoEF.Blazor.Server/Pages/_Host.cshtml page as described in the following topic: Add DevExtreme to a jQuery Application.

  3. Add the TreeList.razor Razor component to the BlazorComponents project.

    The following table describes the APIs implemented in this component:

    API Type Description
    GetDataAsync parameter Encapsulates a method that fetches data on demand.
    FieldNames parameter Stores an array of field names.
    GetFieldDisplayText parameter Encapsulates a method that returns field captions.
    GetKey parameter Encapsulates a method that returns the current key value.
    HasChildren parameter Encapsulates a method that determines whether the currently processed node has child nodes.
    RowClick parameter Encapsulates a method that handles an event when users click a row.
    SelectionChanged parameter Encapsulates a method that handles an event when users change selection.
    OnRowClick and OnSelectionChanged methods Used to raise the RowClick and SelectionChanged events.
    OnAfterRenderAsync method Initializes the necessary IJSObjectReference, ElementReference, and DotNetObjectReference fields for interaction with the DevExtreme TreeList widget.
    OnGetDataAsync method Creates a dictionary of field name-value pairs. This method is called from JavaScript code to fetch data based on the passed parent key value.
    Refresh method Calls the JavaScript TreeList.refresh method.
  4. Add the treeListModule.js script with the TreeList API to the BlazorComponents\wwwroot folder. In the script, configure TreeList to load data on demand as described in the following article: Load Data on Demand. Use the DotNetObjectReference object to call the declared .NET OnGetDataAsync method and fetch data. Handle the TreeList.rowClick and TreeList.selectionChanged events to call the declared .NET OnRowClick and OnSelectionChanged methods.

See also:

Component Model

  1. In the Blazor project (TreeListDemoEF.Blazor.Server), create the ComponentModelBase descendant and name it TreeListModel.cs.

    The following table describes the APIs implemented in this component:

    API Type Description
    GetDataAsync property Encapsulates a method that fetches data on demand.
    FieldNames property Stores an array of field names.
    GetFieldDisplayText property Encapsulates a method that returns field captions.
    GetKey property Encapsulates a method that returns the current key value.
    HasChildren property Encapsulates a method that determines whether the currently processed node has child nodes.
    RowClick, SelectionChanged, RefreshRequested events Occur when users click a row and change selection.
    OnRowClick, OnSelectionChanged, Refresh methods Used to raise the corresponding events.
  2. Create EventArgs descendants to pass key values to the RowClick and SelectionChanged event handlers. See these classes in the following file: TreeListModel.cs.

Component Renderer

  1. In the Blazor project (TreeListDemoEF.Blazor.Server), create a new Razor component and name it TreeListRenderer.razor. This component renders the TreeList component from the RCL project.
  2. Ensure that the component’s Build Action property is set to Content.
  3. Declare the required parameters and implement the IDisposable interface.

List Editor

  1. Create a ListEditor descendant, apply the ListEditorAttribute to this class, and pass an ITreeNode type as a parameter.
  2. Implement the IComplexListEditor interface. In the IComplexListEditor.Setup method, initialize an Object Space instance.

The following table describes the API implemented in this List Editor:

API Type Description
SelectionType property Returns SelectionType.Full. This setting allows users to open the Detail View by click.
CreateControlsCore method Returns an instance of the TreeList component.
AssignDataSourceToControl method Assigns the List Editor’s data source to the component model. If the data source implements the IBindingList interface, this method handles data change notifications.
OnControlsCreated method Passes methods to the created delegates, initializes the arrays of field names, and subscribes to the component model’s RowClick and SelectionChanged events.
BreakLinksToControls method Unsubscribes from the component model’s events and resets its data to release resources.
Refresh method Calls the component model's Refresh method to update the List Editor layout when its data is changed.
GetSelectedObjects method Returns an array of selected objects.

Supported Data Access mode

As the created tree list editor supports only the 'Client' Data Access mode, you need to use the RegisterEditorSupportedModes method as shown here:

DataAccessModeHelper.RegisterEditorSupportedModes(typeof(TreeListEditor), new[] { CollectionSourceDataAccessMode.Client });

Files to Review

Documentation

More Examples

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)