Go to content

Bulletcode.NET

MVVM

Bulletcode.NET contains a Bulletcode.Desktop package for building Windows-only desktop applications using the MVVM architecture, based on the WPF framework. See the Introduction for more information about installing the Bulletcode.NET NuGet packages.

Application builder

The desktop application builder is similar to the web application builder which is part of ASP.NET Core. It provides support for dependency injection, configuration and logging for desktop applications. It also includes a basic executor for background services implementing IHostedService.

The following example shows the Main() method of an application using the desktop application builder:

public class Program
{
    [STAThread]
    public static void Main()
    {
        var builder = DesktopAplication.CreateBuilder();

        builder.Logging.AddTextFile();

        ConfigureServices( builder.Services );

        var app = builder.Build();

        app.Run();
    }
}

The configuration manager includes environment variables with the DOTNET_ prefix, and three settings files: appsettings.json, appsettings.ENV.json (where ENV is the name of the environment), and appsettings.local.json. See Configuration for more information.

The host environment is initialized with the following information:

  • ApplicationName — the name of the entry assembly.
  • ContentRootPath — the directory containing the entry assembly.
  • EnvironmentName — taken from DOTNET_ENVIRONMENT, defaults to Production.

The ContentRootFileProvider property of the host environment is not initialized.

The logging builder is initialized using the "Logging" section of the configuration. No logging providers are registered by default. The AddTextFile() extension method for ILoggingBuilder registers the text file logging provider. See Logging for more information.

Both the IHostEnvironment and IConfiguration are added as singletons to the service provider. The services required for logging and managing options are also registered. See Dependency Injection for more information.

The application should register additional services and specify the application class and the main window class, for example:

private static void ConfigureServices( IServiceCollection services )
{
    services.UseApplication<App>();
    services.UseMainWindow<MainWindow>();
}

The App class should inherit the WPF Application class, and should contain a reference to the application’s resource dictionary. The MainWindow class should inherit the WPF Window class.

The application and main window objects are created using the service provider, so they can have dependencies. However, the recommended approach is to add any dependencies to the view models, and not directly to the application or window classes.

To create a main window with an associated view model, which will be set as its data context, use the second variant of the UseMainWindow() method, for example:

services.UseMainWindow<MainWindow, MainWindowViewModel>();

Setup services

When a service is registered using the IDesktopApplicationSetup, its methods will be automatically called by the application builder:

  • Initialize() — immediately after the service provider is created
  • Startup() — after the application and window objects are created, immediately before the main window is shown

View models

The BaseViewModel, ObservableValidator and ObservableObject classes can be used as base classes for your view models. See View Models for more information.

BaseGridViewModel

The BaseGridViewModel class can be used as the base of view models for views containing a DataGrid control with paging, sorting and filtering. The template parameter of this class specifies the type of grid items. It has the following properties:

  • Items — the collection of items on the current page, which should be specified as the items source for the DataGrid
  • CurrentPage — the index of the current page (starting from 0)
  • TotalCount — the total number of items
  • PageSize — the number of items displayed on a single page
  • SortDescriptor — stores the name of the property used for sorting and the direction of sorting; it can be bound to the DataGrid using the DataGridSortBindingBehavior (see Controls for more information)
  • PaginationLabel — a read-only property which contains information about displayed items and the total number of items
  • ShowPreviousPageCommand — a command which navigates to the previous page
  • ShowNextPageCommand — a command which navigates to the next page
  • RequestedPage — a protected property which contains the index of the page which should be retrieved by the PopulateRows() method

The class which inherits BaseGridViewModel must implement the abstract PopulateRows() method. This method should retrieve items from an external source, for example an API, using the RequestedPage and SortDescriptor properties. The method should update the Items, CurrentPage and TotalCount properties. Asynchronous operations should be wrapped in the ShowBusy() method of the INaviationProvider service.