Windows 8 Consumer Preview and Visual dStudio 11 Beta – Customizing Settings Charm (Part 4/11)
Before Windows 8 every application invented its own way to present application settings. Here are very few of them:




Some apps even provided standalone applications to manage settings. Also from settings storage perspective every developer had to decide when, where and how those settings are saved and in some cases synchronized between different user’s machines.
With Windows 8 Metro applications most of those questions and hard choices are gone. Every Metro application can use system-wide standard way to present settings and collect them in predictable and system-standard way. Windows 8 provides “Settings” charm which is accessible as a part of system menu.

By default, if not customized, application will have only one (system provisioned) settings entry – Permissions.This menu item shows basic application package information and special permissions application uses (as provided by application manifest)


Application developer can customize the contents of Settings charm by adding custom menu entries (commands) and handling it in application.
When user opens the settings charm application gets a chance to provide custom commands. To get notified about this request subscribe to CommandsRequested event of SettingsPane class as in the following code snippet:
//Setup settings panel
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
Application can provide customized UI to launch the settings charm. To show this charm invoke the following code as response your application corresponding UI request:
SettingsPane.Show();
Once user invokes this functionality or opens Settings charm by system gesture OnCommandsRequested handler being executed. In order to add new item (Command) to settings pane you have to create new instance of SettignsCommand class providing CommandId, Label and handler function (which will be executed in user invokes the command):
void BlankPage_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
SettingsCommand SyncSettingsCommand = new SettingsCommand("SyncSettings", SyncSettings ? "Disable settings sync" : "Enable settings sync", new UICommandInvokedHandler(onSettingsSync));
args.Request.ApplicationCommands.Add(SyncSettingsCommand);
//...
SettingsCommand helpCommand = new SettingsCommand("HelpPage", "Help", new UICommandInvokedHandler(onHelpCommand));
args.Request.ApplicationCommands.Add(helpCommand);
}
private void onSettingsSync(IUICommand command)
{
//Do application logic for setting change
SyncSettings = !SyncSettings;
SaveSettings();
}
private void onHelpCommand(IUICommand command)
{
helpPage.Margin = ThicknessHelper.FromUniformLength(0);
}
Note: Most of the commands were skipped for brevity of the code. SaveSettigs functionality will be discussed in my next post.
Customized settings charm (permissions are provided by OS):

Let us see two typical settings commands: direct value change (like Sync settings) and “link” to some additional settings screen. In both cases, taping (clicking) the command on settings charm dismisses the charm. While in case of Sync settings the command is responsible for direct change of the setting, in case of Help we want to present some additional functionality and screen. Unfortunately it is not possible to integrate custom user control into settings charm, so application developer must provide the UI and system-like behavior.
System-like behavior assumes that changes made in custom panel are implemented/saved as they done, panel enables navigating back to system settings pane and supports light dismiss – clicking anywhere else of the panel dismisses the panel and saves the settings.
In my application I created simple user control, which were initially placed off main screen (using negative margin):
<local:HelpPage x:Name="helpPage" Margin="0,0,-346,0" HorizontalAlignment="Right">
<local:HelpPage.Transitions>
<TransitionCollection>
<RepositionThemeTransition/>
</TransitionCollection>
</local:HelpPage.Transitions>
</local:HelpPage>
I defined transition effect for my custom control to enable repositioning using system-like animation (RepositionThemeTransition). Using this effect helps mimic “sliding out” effect like real system-provided settings charm does. Final custom settings panel looks like the following:


To support light-dismiss I’ve subscribed to PointerPressed event on parent UI element (in my case – Grid):
<Grid PointerPressed="Grid_PointerPressed">
And in handler function simply changed the Margin property of the control:
private void Grid_PointerPressed(object sender, Windows.UI.Xaml.Input.PointerEventArgs e)
{
//Change margin only if control is visible
if (helpPage.Margin.Right == 0)
helpPage.Margin = ThicknessHelper.FromLengths(0, 0, -346, 0);
}
At the control level, I subscribed to back button Click event:
<Button x:Name="backButton" Click="GoBack" Style="{StaticResource BackButtonStyle}" Margin="0"/>
and in event handler I re-opened settings pane and hided the panel:
private void GoBack(object sender, RoutedEventArgs e)
{
//Reopen settings pane
SettingsPane.Show();
//Hide this panel
this.Margin = ThicknessHelper.FromLengths(0, 0, -346, 0);
}
Small trick here – you control must subscribe and handle PointerPressed event, otherwise parent control (Grid in my case) will dismiss it on any tap/click, even on control itself:
private void UserControl_PointerPressed(object sender, PointerEventArgs e)
{
e.Handled = true;
}
The control logic (the rest of code you have to write) is absolutely unique for each application.
The working settings pane with custom help panel demonstrated here:
Integrating custom panel in settings panel
Using the techniques described above you application supports standard Windows 8 settings behaviour.
That’s it for now.
Stay tuned for next post.
Alex