Clone our Wealth-Lab 8 Extension Demo project on GitHub to get a head start in developing your own Extensions!

WealthLab Client Extension API

A Client Extension integrates custom user interface functionality into WealthLab 9. Client Extensions can add items to the WealthLab Extensions menu, open custom child windows, add Preferences pages, integrate with Workspaces, and register Help content. Client Extensions are implemented using two base classes:

  • WL8ExtensionBase - Provides application-level initialization and Help System integration. It is defined in WealthLab.Core and does not depend on WPF.
  • WL8ClientExtensionBase - Provides Windows-specific UI integration, including Extensions menu items, child windows, and Preferences pages. It is defined in WealthLab.WPF.

Note: The class names WL8ExtensionBase and WL8ClientExtensionBase have been retained in WealthLab 9 for backward compatibility with extensions originally developed for WealthLab 8.

Build Environment

You can create a WL8 Client Extension in a .NET development tool such as Visual Studio 2026. Create a class library project that targets .NET10, then reference the WealthLab.WPF library DLL that you'll find in the WL9 installation folder.

Your WL8 Client Extension will be a class in this library that descends from WL8ClientExtensionBase, which is defined in the WealthLab.WPF library, in the WealthLab.WPF namespace. After you implement and build your library, simply copy the resulting assembly DLL into the WL9 installation folder. The next time WL9 starts up, it will discover your WL8 Client Extension, making it available in appropriate locations of the WL9 user interface.

Visual Studio 2026 Build Environment

Accessing the Host (WL9) Environment

The IHost interface provides access to the current WealthLab environment. Extensions can use it to retrieve application-level information and services, such as the location of the user's WealthLab data folder or the DataSets defined by the user.

You can access the current IHost instance from anywhere in your extension through the WLHost singleton and its Instance property. For example, the following code retrieves the path to the user's WealthLab data folder:

string folder = WLHost.Instance.DataFolder;

Use WLHost.Instance whenever your extension needs access to functionality exposed by the IHost interface.

WL8ExtensionBase

WL8ExtensionBase is defined in WealthLab.Core and provides application-level functionality that does not depend on WPF. WealthLab instantiates classes derived from WL8ExtensionBase during application startup. Create a class derived from WL8ExtensionBase when your extension requires one-time initialization or wants to register pages with the WealthLab Help System.

Name

Override the Name property to identify your extension.

public abstract string Name

For example:

public override string Name =>
    "My Extension";

If your extension also contains a WL8ClientExtensionBase implementation, both classes should return the same Name.

Initialize

public virtual void Initialize()

Override this method to perform one-time initialization. WealthLab calls Initialize once when the extension is loaded during application startup. For example:

public override void Initialize()
{
    // Perform extension initialization.
}

Integrating with the Help System

A Client Extension can add its own documentation pages to the WealthLab Help System. Help pages are normally registered from the WL8ExtensionBase.Initialize method.

InsertPage

Use:

HelpManager.InsertPage(...)

to add a page to the Help contents hierarchy. The supplied string consists of page names separated by backslashes. Client Extension documentation should normally be placed beneath the top-level Extensions section. For example:

public override void Initialize()
{
    HelpManager.InsertPage(
        @"Extensions\MyExtension");

    HelpManager.InsertPage(
        @"Extensions\MyExtension\SomeDetails");

    HelpManager.InsertPage(
        @"Extensions\MyExtension\MoreDetails");
}

The top-level extension Help page should normally use the same name as the Token of the extension's primary ChildWindow. Additional pages can be nested beneath it.

Help Content Files

Each Help page registered with InsertPage should have a corresponding Markdown file installed into WealthLab's Help content. For example:

Extensions\MyExtension

would correspond to:

MyExtension.md

and:

Extensions\MyExtension\SomeDetails

would correspond to:

SomeDetails.md

The files use Markdown formatting.

HelpToken

A ChildWindow normally uses its Token to associate itself with a Help page. If the ChildWindow should use a different Help page, override its HelpToken property.

WL8ClientExtensionBase

WL8ClientExtensionBase is defined in WealthLab.WPF and provides the Windows-specific Client Extension functionality. Create a class derived from WL8ClientExtensionBase to:

  • Add menu items to the Extensions menu.
  • Open ChildWindows.
  • Add Preferences pages.
  • Restore extension windows from Workspaces.
  • Respond to action links in Help pages.

As with WL8ExtensionBase, the WL8 prefix remains in the class name for backward compatibility.

Name

public abstract string Name

Override this property to return the descriptive name of the Client Extension. If the extension also has a WL8ExtensionBase-derived class, return the same Name from both. For example:

public override string Name =>
    "Candlesticks";

Adding Items to the Extensions Menu

GetMenuItems

public virtual List<MenuItem> GetMenuItems()

Override this method to return the WPF MenuItem instances that should be added to WealthLab's Extensions menu. You can create MenuItems directly or use CreateExtensionMenuItem. For example:

public override List<MenuItem> GetMenuItems()
{
    List<MenuItem> items =
        new List<MenuItem>();

    items.Add(
        CreateExtensionMenuItem(
            "My Extension",
            Glyph,
            MenuItemClick));

    return items;
}

CreateExtensionMenuItem

public MenuItem CreateExtensionMenuItem(
    string caption,
    ImageSource glyph,
    RoutedEventHandler reh,
    bool reversableImage = false)

Creates a WPF MenuItem configured for use in the Extensions menu. The parameters are:

  • caption - Text displayed by the menu item.
  • glyph - Image displayed with the menu item.
  • reh - RoutedEventHandler called when the user clicks the item.
  • reversableImage - Controls whether WealthLab can reverse the glyph for Dark Theme display.

The event handler will typically create and display a ChildWindow. For example:

private void MenuItemClick(
    object sender,
    RoutedEventArgs e)
{
    CreateChildWindow();
}

Interacting with the Parent Main Window

WealthLab supports multiple Main Windows. A WL8ClientExtensionBase instance is associated with a specific Main Window and exposes that context through IWLClientHost.

MyClientHost

public IWLClientHost MyClientHost

Returns the IWLClientHost associated with the Main Window currently hosting the Client Extension. Use this interface to interact with the corresponding WealthLab window. One of its most important methods is ShowExtensionChildWindow, which displays a custom ChildWindow.

Child Windows

Client Extensions can open custom windows inside the WealthLab desktop environment. Your custom window should derive from:

ChildWindow

Consult the ChildWindow class reference for details about creating WealthLab child windows. To display one, call:

MyClientHost.ShowExtensionChildWindow(...)

For example:

private ChildWindow CreateChildWindow()
{
    MyChildWindow cw =
        new MyChildWindow();

    MyClientHost.ShowExtensionChildWindow(
        cw,
        "My Extension",
        Glyph);

    return cw;
}

Adding Preferences Pages

public virtual List<TabPage> PreferencePages

Override this property to add custom pages to the WealthLab Preferences tool. Return a list of TabPage instances. TabPage is defined in WealthLab.WPF and derives from WPF UserControl. For example:

public override List<TabPage> PreferencePages
{
    get
    {
        return new List<TabPage>
        {
            new MyPreferencesPage()
        };
    }
}

Restoring Child Windows from Workspaces

WealthLab Workspaces can save and restore Main Windows and the ChildWindows they contain. Client Extension ChildWindows should participate in this process.

GetChildWindow

public virtual ChildWindow GetChildWindow(
    string token)

WealthLab calls this method when restoring an extension ChildWindow from a Workspace. Examine the supplied token and return the corresponding ChildWindow instance. Each ChildWindow exposes its own Token property. For example:

public override ChildWindow GetChildWindow(
    string token)
{
    if (token != "MyExtension")
        return null;

    return new MyChildWindow();
}

Return null when the token does not belong to your Client Extension. The Token should uniquely identify the type of ChildWindow being restored.

Help Action Tokens

Help pages can contain special links that open a Client Extension window directly. For example:

[Take me there now](action:extension:MyExtension)

When the user clicks the link, WealthLab calls:

public virtual bool ProcessHelpToken(
    string token)

Override this method to recognize your extension's Help tokens. If the token matches one of your ChildWindows, display the window and return true. Otherwise, return false. For example:

public override bool ProcessHelpToken(
    string token)
{
    if (token == "MyExtension")
    {
        CreateChildWindow();
        return true;
    }

    return false;
}

Using the same string for:

  • The ChildWindow Token
  • The extension's main Help page
  • The Help action token

helps keep the integration consistent.

Complete Example

The following example shows a Client Extension that:

  • Adds an item to the Extensions menu.
  • Opens a ChildWindow.
  • Supports Workspace restoration.
  • Responds to a Help action token.
  • Adds a Preferences page.
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WealthLab.Core;
using WealthLab.WPF;

namespace WealthLab.Candlesticks
{
    public class CandlesticksClientExtension :
        WL8ClientExtensionBase
    {
        public override string Name =>
            "Candlesticks";

        public override List<MenuItem> GetMenuItems()
        {
            List<MenuItem> items =
                new List<MenuItem>();

            MenuItem item =
                CreateExtensionMenuItem(
                    "Candlestick Genetic Evolver",
                    Glyph,
                    MenuItemClick);

            items.Add(item);

            return items;
        }

        public override ChildWindow GetChildWindow(
            string token)
        {
            if (token != "Candlesticks")
                return null;

            return CreateChildWindow();
        }

        public override bool ProcessHelpToken(
            string token)
        {
            if (token == "Candlesticks")
            {
                CreateChildWindow();
                return true;
            }

            return false;
        }

        public override List<TabPage> PreferencePages
        {
            get
            {
                return new List<TabPage>
                {
                    new prefCandlesticks()
                };
            }
        }

        private void MenuItemClick(
            object sender,
            RoutedEventArgs e)
        {
            CreateChildWindow();
        }

        private ChildWindow CreateChildWindow()
        {
            cwCandlesticks cw =
                new cwCandlesticks();

            MyClientHost.ShowExtensionChildWindow(
                cw,
                "Candlestick Genetic Evolver",
                Glyph);

            return cw;
        }

        private ImageSource Glyph =>
            GlyphManager.GetImageSource(
                "WealthLab.Candlesticks.WPF." +
                "Glyphs.Candlesticks.png",
                this);
    }
}

This pattern provides the standard foundation for extensions that add new interactive tools to the WealthLab 9 desktop interface.