WPF Application - kaisu1986/ATF GitHub Wiki

Table of Contents

WinForms and WPF applications use ATF in similar ways. This section discusses their differences in basic application structure. The other sections in ATF Application Basics and Services also mention similarities and differences between WinForms and WPF.

For an example of a WPF ATF application, see the ATF Wpf App Sample. For a WinForms application that shares code with this WPF sample and helps clarify the similarities and differences between the two, see the ATF Win Forms App Sample.

App.xaml

App.xaml is the XAML file in which the WPF application is set up:

<atf:AtfApp x:Class="WpfApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:atf="http://www.sce.net/Atf.Gui.Wpf">
</atf:AtfApp>

This partially defines the class WpfApp.App, which is derived from the ATF class AtfApp. The rest of the WpfApp.App class definition is in the C# file App.xaml.cs, which sets up the MEF catalog, as discussed in MEF Setup.

AtfApp Class

The AtfApp class is the base ATF WPF application class and derives from System.Windows.Application. You should derive WPF applications from this class to avoid rewriting common code. AtfApp implements IComposer, which is an interface for ComposablePart and CompositionContainer used for WPF applications with MEF.

AtfApp's constructor performs some of the same set up functions as the WinForms Main() function discussed in Initial Setup:

public AtfApp()
{
    // Setup thread name and culture
    Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CurrentCulture;
    Thread.CurrentThread.Name = "Main";

    // Ensure the current culture passed into bindings is the OS culture.
    // By default, WPF uses en-US as the culture, regardless of the system settings.
    FrameworkElement.LanguageProperty.OverrideMetadata(
        typeof(FrameworkElement), new FrameworkPropertyMetadata(
            XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag)));
}

Much of AtfApp is dedicated to composing components with MEF, which is discussed next in MEF Setup.

MEF Setup

If a WPF application uses MEF, it needs to specify the components it uses. This section discusses a way to do this using AtfApp.

AtfApp has an OnStartup() method that is called when a WPF application starts up:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    if (Compose())
    {
        OnCompositionBeginning();

        foreach (var initializable in m_initializables)
            initializable.Value.Initialize();

        OnCompositionComplete();

        m_mainWindow.ShowMainWindow();
    }
    else
    {
        Shutdown();
    }
}

OnStartup() calls the Compose() method to compose the MEF components. In turn, Compose() calls the abstract method GetCatalog(), which actually sets up the MEF catalog. OnStartup() also initializes all the MEF components using the ATF IInitializable.Initialize() method.

The ATF application should provide a GetCatalog() implementation that sets up the MEF catalog. Here's how the ATF Wpf App Sample does it in App.xaml.cs, defined in the partial class App:

public partial class App : AtfApp
{
    protected override AggregateCatalog GetCatalog()
    {
        var typeCatalog = new TypeCatalog(
            typeof(SettingsService),                // persistent settings and user preferences dialog
            typeof(CommandService),                 // handles commands in menus and toolbars
            typeof(ControlHostService),             // docking control host
            typeof(AtfUsageLogger),                 // logs computer info to an ATF server
            typeof(CrashLogger),                    // logs unhandled exceptions to an ATF server
            typeof(UnhandledExceptionService),      // catches unhandled exceptions, displays info, and gives user a chance to save
            typeof(ContextRegistry),                // central context registry with change notification
            typeof(StandardFileExitCommand),        // standard File exit menu command
            typeof(FileDialogService),              // standard Windows file dialogs
            typeof(DocumentRegistry),               // central document registry with change notification
            typeof(StandardFileCommands),           // standard File menu commands for New, Open, Save, SaveAs, Close
            typeof(AutoDocumentService),            // opens documents from last session, or creates a new document, on startup
            typeof(RecentDocumentCommands),         // standard recent document commands in File menu
            typeof(MainWindowTitleService),         // tracks document changes and updates main form title
            typeof(WindowLayoutService),            // service to allow multiple window layouts
            typeof(WindowLayoutServiceCommands),    // command layer to allow easy switching between and managing of window layouts
            typeof(SchemaLoader),                   // loads schema and extends types
            typeof(MainWindow),                     // main app window (analog to 'MainForm' in WinFormsApp)
            typeof(Editor),                         // Sample editor class that creates and saves application documents
            typeof(PythonService),                  // scripting service for automated tests
            typeof(ScriptConsole),                  // provides a dockable command console for entering Python commands
            typeof(AtfScriptVariables),             // exposes common ATF services as script variables
            typeof(AutomationService)              // provides facilities to run an automated script using the .NET remoting service
        );

        return new AggregateCatalog(typeCatalog, StandardInteropParts.Catalog, StandardViewModels.Catalog);
    }
}

The GetCatalog() method returns an AggregateCatalog, which contains the TypeCatalog with the components the sample application uses — as well as a couple of ComposablePartCatalog objects containing WPF versions of ATF components that are generally useful for WPF applications: StandardInteropParts.Catalog and StandardViewModels.Catalog. For more information on StandardInteropParts, see Using WinForms Controls in WPF.

Application Exit

AtfApp also provides a OnExit() called when the WPF application exits. OnExit() disposes of MEF components' resources. You can override it to perform additional clean up. Here is the base method:

protected override void OnExit(ExitEventArgs e)
{
    base.OnExit(e);

    foreach (var disposable in m_disposables)
    {
        disposable.Value.Dispose();
    }

    if (Container != null)
    {
        Container.Dispose();
    }
}

Topics in this section

⚠️ **GitHub.com Fallback** ⚠️