Ticket T991322
Visible to All Users
Duplicate

We have closed this ticket because another page addresses its subject:

Blazor - How to integrate a custom DevExtreme component and bind it to a data source

Blazor - How to pass View and ViewItem parameters to a Blazor component that shows a DevExtreme widget

created 4 years ago (modified 4 years ago)

[DevExpress Support Team: CLONED FROM T943982: Blazor - How to integrate a custom DevExtreme component and bind it to a data source]

What if I wanted to pass the View (or, at least, the Oid of the object) to the Blazor component, if the ViewItem is added to a DetailView and not to a ListView?

Comments (2)
Anatol (DevExpress) 4 years ago

    Hello Emanuele,

    You can access the current object in a custom View Item using the ViewItem.CurrentObject property. To access the current View, use the ViewItem.View property. You can pass these values to your Razor component when you initialize it in the CreateControlCore method. To update these values dynamically (e.g., from ViewController), you can implement a model for your Razor component. See an example at How to: Implement a Property Editor Based on a Custom Component (Blazor).
    If this does not help, please describe your task in greater detail.

      Hi,
      here is my code:

      C#
      namespace BlazorMultiAuth.Module.Blazor.Editors { /// <summary> /// /// </summary> public interface IModelDiagramViewItem : IModelViewItem { public DiagramObject DiagramObject { get; set; } public View View { get; set; } } /// <summary> /// /// </summary> [ViewItem(typeof(IModelDiagramViewItem))] public class IDiagramViewItem : ViewItem, IComplexViewItem { XafApplication application; //private object _itemObject; //private View _itemView; /// <summary> /// /// </summary> class ComponentContentHolder : IComponentContentHolder { private readonly RenderFragment componentContent; private readonly object componentObject; private readonly View componentView; public ComponentContentHolder(RenderFragment componentContent, object componentObject, View componentView) { this.componentContent = componentContent; this.componentObject = componentObject; this.componentView = componentView; } //RenderFragment IComponentContentHolder.ComponentContent => componentContent; RenderFragment IComponentContentHolder.ComponentContent => Diagram.Create(componentContent, componentObject, componentView); } public IDiagramViewItem(IModelDiagramViewItem model, Type classType) : base(classType, model.Id) { //this._itemObject = model.DiagramObject; //this._itemView = model.View; } protected override object CreateControlCore() { NavigationManager navigationManager = ((BlazorApplication)application).ServiceProvider.GetRequiredService<NavigationManager>(); Uri url = navigationManager.ToAbsoluteUri("diagram"); RenderFragment iframeFragment; iframeFragment = b => { b.OpenElement(0, "div"); b.OpenElement(1, "iframe"); b.AddAttribute(2, "src", url); b.AddAttribute(3, "width", "90%"); b.AddAttribute(4, "height", "550px"); b.CloseElement(); b.CloseElement(); }; object itemObject = this.CurrentObject; View itemView = this.View; return new ComponentContentHolder(iframeFragment, itemObject, itemView); } void IComplexViewItem.Setup(IObjectSpace objectSpace, XafApplication application) { this.application = application; } } }

      And the Razor component:

      Razor
      @using Microsoft.JSInterop @page "/diagram" @implements IDisposable @inject IJSRuntime JSRuntime @inject DevExpress.ExpressApp.Blazor.Services.IXafApplicationProvider ApplicationProvider <h3>Diagram</h3> <div id="diagram" style="width:90%; height: 500px;"></div> @code { private DevExpress.ExpressApp.IObjectSpace objectSpace; [Parameter] public RenderFragment ComponentModel { get; set; } [Parameter] public object ComponentObject { get; set; } [Parameter] public DevExpress.ExpressApp.View ComponentView { get; set; } public static RenderFragment Create(RenderFragment componentModel, object componentObject, DevExpress.ExpressApp.View componentView) => @<Diagram ComponentModel=@componentModel ComponentObject=@componentObject ComponentView=@componentView/>; ... protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) { return; } var app = ApplicationProvider.GetApplication(); objectSpace = app.CreateObjectSpace(typeof(BlazorMultiAuth.Module.BusinessObjects.DiagramObject)); ... } private DiagramUpdateInvokeHelper diagramUpdateInvokeHelper; protected override void OnInitialized() { diagramUpdateInvokeHelper = new DiagramUpdateInvokeHelper(UpdateObject); } void IDisposable.Dispose() { objectSpace?.Dispose(); } }

      Anyway, this doesn't work because, while the first is sited in the Module.Blazor project, the second is sited in in the Blazor.Server project (under "Pages" folder), so the Diagram.Create() cannot be called.
      Any solution? Or am I doing something wrong?

      Thanks in advance.

      Answers approved by DevExpress Support

      created 4 years ago (modified 4 years ago)

      Hello Emanuele,

      This design cannot be used together with the solution that is shown in Blazor - How to integrate a custom DevExtreme component and bind it to a data source. The View Item from this solution renders an iframe with a Razor page that is accessed by the "/grid" route. This page is completely autonomous and creates all required XAF entities using an injected IXafApplicationProvider.

      To pass parameters to a Razor component, do not use the iframe element and routing. Please see how a Razor component is declared and created in the following examples:
      How to: Add a Button to a Detail View Using a Custom View Item
      How to: Implement a Property Editor Based on a Custom Component (Blazor)
      How to implement a custom Blazor List Editor based on DxPivotGrid

      Although they do not use DevExtreme widgets, you can render them in Razor components similarly to how they are rendered in Grid.razor from Blazor - How to integrate a custom DevExtreme component and bind it to a data source - override the OnAfterRenderAsync method and use the JSRuntime.InvokeVoidAsync method.
      I modified our example with the DevExtreme Data Grid widget to demonstrate this solution. Please see the attached project. Hope you find it helpful.

        Comments (2)
        DevExpress Support Team 4 years ago

          Hello Emanuele,

          We added more examples that demonstrate how to exchange data between custom Razor components and XAF:
          How to: Use a Custom Component to Implement List Editor (Blazor).
          Create an ASP.NET Core Blazor-Specific View Item

          Please feel free to contact us if you have any questions.

            Hi Jenny,

            thanks for the examples you shared with me, I've already solved the problem with the documentation provided to me by Anatol.

            Best regards.

            Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

            Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.