Skip to content

SettingsService Component

Gary edited this page Nov 3, 2014 · 2 revisions

Table of Contents

The SettingsService component manages user-editable settings (preferences) and the persistence of these application settings. You can specify which settings to persist, and they are saved in an XML file. SettingsService implements the ISettingsService interface.

This component, or one like it, is useful to any application with preferences and is used by nearly all the ATF samples. To use it, add SettingsService to the MEF TypeCatalog of the application. Applications also need to add the CommandService component, because SettingsService imports ICommandService. After SettingsService is added, you can specify settings you want saved.

SettingsService is required by other components in the Application Shell: ControlHostService and CommandService. ControlHostService uses it to save the state of the dock panel and whether the UI is locked. CommandService saves keyboard shortcuts and the command icon size.

SettingsService does not interact with the rest of an application's GUI, so it can be used with both WinForms and WPF. It does present a dialog allowing a user to edit preferences.

ISettingsService Interface

The ISettingsService interface allows registering the settings you want to preserve and present them to the user with these methods:

  • RegisterSettings(): Register all the settings you want to preserve, including user-editable ones.
  • RegisterUserSettings(): Register the settings you allow a user to change.
  • PresentUserSettings(): Present the settings to a user for editing.
Each setting is described by a PropertyDescriptor, and the registration methods take a PropertyDescriptor array parameter.

Note the following:

  • Registering a setting adds it to the saved settings; it does not replace the existing set.
  • Calling RegisterUserSettings() only indicates that the setting is to be user-visible; you must call RegisterSettings() for this setting to persist it.

Getting a SettingsService Object

You need a SettingsService object on which to invoke the ISettingsService methods to register settings. You get this by using MEF to import the SettingsService component you added to the application.

For example, the ATF Timeline Editor Sample uses an [ImportingConstructor] attribute to import the SettingsService object in the constructor parameter settingsService, which is then saved in the field m_settingsService:

[ImportingConstructor]
public TimelineEditor(
    IControlHostService controlHostService,
    ICommandService commandService,
    IContextRegistry contextRegistry,
    IDocumentRegistry documentRegistry,
    IDocumentService documentService,
    IPaletteService paletteService,
    ISettingsService settingsService)
{
    ...
    m_settingsService = settingsService;

For more information on using MEF exporting and importing, see MEF Attributes.

Specifying Saved Settings

This example from the ATF Timeline Editor Sample creates property descriptors for the settings to be saved, and then registers these settings.

var settings = new BoundPropertyDescriptor[] {
    new BoundPropertyDescriptor(typeof(D2dTimelineRenderer),
        () => D2dTimelineRenderer.GlobalHeaderWidth,
        "Header Width", "Appearance", "Width of Group/Track Header"),
    new BoundPropertyDescriptor(typeof(D2dTimelineRenderer),
        () => D2dTimelineRenderer.GlobalKeySize, "Key Size", "Appearance", "Size of Keys"),
    new BoundPropertyDescriptor(typeof(D2dTimelineRenderer),
        () => D2dTimelineRenderer.GlobalMajorTickSpacing, "Major Tick Spacing", "Appearance", "Pixels between major ticks"),
    new BoundPropertyDescriptor(typeof(D2dTimelineRenderer),
        () => D2dTimelineRenderer.GlobalPickTolerance, "Pick Tolerance", "Behavior", "Picking tolerance, in pixels"),
    new BoundPropertyDescriptor(typeof(D2dTimelineRenderer),
        () => D2dTimelineRenderer.GlobalTrackHeight, "Track Height", "Appearance", "Height of track, relative to units of time"),

    //manipulator settings
    new BoundPropertyDescriptor(typeof(D2dSnapManipulator), () => D2dSnapManipulator.SnapTolerance, "Snap Tolerance", "Behavior",
        "The maximum number of pixels that a selected object will be snapped"),
    new BoundPropertyDescriptor(typeof(D2dSnapManipulator), () => D2dSnapManipulator.Color, "Snap Indicator Color", "Appearance",
        "The color of the indicator to show that a snap will take place"),
    new BoundPropertyDescriptor(typeof(D2dScaleManipulator), () => D2dScaleManipulator.Color, "Scale Manipulator Color", "Appearance",
        "The color of the scale manipulator")            };
m_settingsService.RegisterUserSettings("Timeline Editor", settings);
m_settingsService.RegisterSettings(this, settings);

Note that the BoundPropertyDescriptor array is used as a parameter in both RegisterUserSettings() and RegisterSettings() calls. The m_settingsService field was set to a SettingsService object as shown previously in Getting a SettingsService Object.

This shorter example from the ControlHostService component illustrates that you can call RegisterSettings() repeatedly to add settings:

m_settingsService.RegisterSettings(this,
    new BoundPropertyDescriptor(this, () => DockPanelState, "DockPanelState", null, null));
m_settingsService.RegisterSettings(this,
    new BoundPropertyDescriptor(this, () => UILocked, "UILocked", null, null));

Displaying User Settings

SettingService implements the PresentUserSettings() method to show the settings to a user for editing. In addition, it registers and implements a command to display the dialog. The command is activated by the Edit > Preferences menu item. Preferences are displayed in a tree list editor.

Topics in this section

Clone this wiki locally