Table of Contents

Using a custom ScreenType

How to create a custom screen by constructing a custom ScreenType

If you want more control over how a screen looks, or if you want to show off a combination of data for which we have no data model, you can build a truly custom screen by creating and using a custom ScreenType. This is a bit more difficult than using a built-in ScreenType, but also affords you more freedom. You must:

  1. Create a ProjectFile and configure it
  2. Make sure the DynamicWeb 10 application loads Views from your custom project
  3. Add content to the custom screen

Creating the custom project

Create a project that uses the Razor class library SDK (Microsoft.NET.Sdk.Razor), so your Razor views compile and embed into the assembly:

  • Use the Microsoft.NET.Sdk.Razor SDK
  • Target net10.0 (Dynamicweb 10 runs on .NET 10)
  • Enable AddRazorSupportForMvc and GenerateEmbeddedFilesManifest
  • Add a framework reference to Microsoft.AspNetCore.App
  • Add a package reference to Microsoft.Extensions.FileProviders.Embedded version 10.0.0

Your project file will look something like this:

    <Project Sdk="Microsoft.NET.Sdk.Razor">
        <PropertyGroup>
            <TargetFramework>net10.0</TargetFramework>
            <Nullable>enable</Nullable>
            <ImplicitUsings>enable</ImplicitUsings>
            <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
            <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
        </PropertyGroup>

        <ItemGroup>
            <EmbeddedResource Include="wwwroot/**/*" />
        </ItemGroup>

        <ItemGroup>
            <FrameworkReference Include="Microsoft.AspNetCore.App" />
        </ItemGroup>

        <ItemGroup>
            <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="10.0.0" />
        </ItemGroup>
    </Project>
Note

With the Microsoft.NET.Sdk.Razor SDK, your .cshtml views are embedded into the assembly automatically — the explicit <EmbeddedResource> entry above is only needed for static wwwroot assets such as JavaScript and CSS.

Add a reference to IRenderBundle

Since this custom project will contain custom views and static files, we need to tell DynamicWeb to look for Views inside this dll when the application is loaded. To do this, you create a class which inherits from Dynamicweb.CoreUI.Rendering.IRenderingBundle:

    public class RenderingBundle : Dynamicweb.CoreUI.Rendering.IRenderingBundle

The class doesn’t need to have any functionality, it just needs to be there.

Add content to the custom screen

The first thing you want to do is create a component – this is where you define what data is available for the screen, as well as set various properties like a header and whether to show our standard search bar, etc. A component should inherit from Dynamicweb.CoreUI.UiComponentBase, but all other content is up to you.

In this example we’re creating a component called ExpressDeliveryWidget which contains a Header and some other data related to shipping and delivery:

  • ShippingLimit: Total hours given to ship a parcel
  • ShippingComment: A comment field
  • RemainingTime: How much time is left to fulfil this shipping request
    public sealed class ExpressDeliveryWidget : UiComponentBase
    {
        public string Header { get; set; } = "";
        public int ShippingLimit { get; set; }
        public string ShippingComment { get; set; } = "";
        public TimeSpan RemainingTime { get; internal set; }
    }

When the component has been defined, it’s time to define how it should look. You do this by creating a matching View. Dynamicweb locates the view by convention, so it must be placed in exactly this folder hierarchy inside your project:

Views\Shared\Components\UiComponentWrapper\

The view file name must be the fully-qualified type name of the component, followed by .cshtml. So a component ExpressDeliveryWidget in the namespace ExpressDelivery.Components maps to the file:

Views\Shared\Components\UiComponentWrapper\ExpressDelivery.Components.ExpressDeliveryWidget.cshtml

This is the same convention the built-in components use — for example Dynamicweb.CoreUI.Displays.Widgets.ProgressDisplay.cshtml. Inside the view, set @model to your component type.

In this case our View looks like this:

@using Dynamicweb.CoreUI.Rendering;
@model ExpressDelivery.Components.ExpressDeliveryWidget

    <div>
        <script src="/ExpressDelivery/js/ExpressDeliveryWidget.js" type="module"></script>
        <express-delivery-widget class="h-100" style="border: var(--dw-border);border-radius: 0.5rem;">
            <div class="info-card-header">
                <div class="flex-fill">
                    <h6 class="dw-group-header">@Model.Header</h6>
                </div>
            </div>

        <div class="widget-content d-flex justify-content-center">
                <div class="list-widget flex-nowrap flex-column w-75">
                    @if (Model.RemainingTime > TimeSpan.Zero)
                    {
                        <div class="flex-row m-3">
                            @await Component.RenderDynamicwebUiComponent(new Dynamicweb.CoreUI.Displays.Widgets.ProgressDisplay((int)Math.Floor(Model.RemainingTime.TotalHours), Model.ShippingLimit){ProgressType = Dynamicweb.CoreUI.Displays.Widgets.ProgressWidgetType.Bar, HideSummary = true})
                            <span>Hours remaining until shipment: @Model.RemainingTime.ToString("d' days 'hh' hours 'mm' minutes 'ss' seconds'") </span>
                        </div>
                    }
                    <div class="flex-row">
                        <h3 style="text-align:center">@Model.ShippingComment</h3>
                    </div>
                </div>
            </div>
        </express-delivery-widget>
    </div>

Next steps

When you’re building custom Views you need to fetch and show data to your users, and often you also want your users to do stuff with the data - like edit and save a user, etc. To do so you can use our built-in Queries and Commands – you can see the built-in types via the API explorer.

When we don’t have standard Queries and Commands suited to your needs you can build something custom.

To top