This project is read-only.

Sample Walkthrough

So you've decided to use YLOD in your app. How to proceed now?

Your Options Class

YLOD does not require you to implement a specific interface or use specific types to function. You simply can use your own custom classes as options data containers, because YLOD will pull all information from these objects automatically using reflection. Let's say in your application you have the following requirements regarding user settings:
  • A selection of choices presented to the user which are mapped to some enum values internally (e.g. to select from different flavors of a feature).
  • The possibility for the user to provide an email address (e.g. for email notifications).
  • A feature that is activated by default, but you want to give the user the possibility to opt-out, once they have confirmed a message (e.g. confirmation because it turns off an essential feature of your app).

What you would do then is simply create a class that holds all that information (if you don't have one already). This you also would have to do without using YLOD.

public enum FeatureChoice
{
    One,
    Two,
    Three
}

public class MyOptions
{
    public FeatureChoice Choice
    {
        get;
        set;
    }

    public string EmailAddress
    {
        get;
        set;
    }

    public bool GreatFeature
    {
        get;
        set;
    }
}

You now already have a working data provider for YLOD!

A First Look

Usually you would navigate to a settings page when the user taps an application bar button or menu entry, but of course you can also do that in response to a button click event or similar actions. To show the options page, simply get access to an instance of your options, and then use the OptionsService like this:

var options = new MyOptions
                    {
                        Choice = FeatureChoice.Two,
                        EmailAddress = "joe.doe@example.com",
                        GreatFeature = true
                    };

OptionsService.Current.Show(options);

And this is the result:

walkthrough01.png

As you can see, this already renders a full options dialog, and values edited in the dialog are written back to your original MyOptions instance. The engine tries to take the property names of your object and do some very basic beautification, i.e. split words by capital letters. Of course there's no validation yet, and none of the additional features are configured.

Using the "Extras"

If you decided to use the "Extras" version of the library (with support for additional data types), then you need to configure the OptionsService to make use of these explicitly. You do that by changing the above code snippet to:

var options = new MyOptions
                    {
                        Choice = FeatureChoice.Two,
                        EmailAddress = "joe.doe@example.com",
                        GreatFeature = true
                    };

// configure the OptionsService to use the "Extras"
OptionsService.Current.OptionsViewFactory = new ExtrasOptionsViewFactory();
OptionsService.Current.OptionsFactoryExtender = new ExtrasOptionsFactoryExtender();

OptionsService.Current.Show(options);

Without these two additional configuration lines, the support for the additional data types in the "Extras" project won't be picked up.

Configuration Through Attributes

All features of YLOD are configured by decorating your properties with attributes. Take a look at the documentation of supported data types to get a detailed idea of all the values you can configure for each type, but common properties you're most likely interested in are the display name, description, group name and display order. Make sure to use the appropriate attribute for the property value you're decorating to avoid problems. All these attributes are conveniently named OptionXYZAttribute, so Intellisense will show you all the options nicely.

The following is an improved version of the above introduced options data container. It adds better display names, descriptions, splits the available options into two groups and plays with the display order:

public class MyOptions
{
    [OptionEnum(DisplayName = "Your feature choice",
        Description = "Please select which flavor of our great feature you want to use in the application.",
        GroupName = "settings",
        DisplayOrder = 1)]
    public FeatureChoice Choice
    {
        get;
        set;
    }

    [OptionString(DisplayName = "Your email address",
        Description = "If you provide an email address here, we will send you periodic updates about our products.",
        GroupName = "newsletter")]
    public string EmailAddress
    {
        get;
        set;
    }

    [OptionBoolean(DisplayName = "Our greatest feature",
        GroupName = "settings",
        DisplayOrder = 0)]
    public bool GreatFeature
    {
        get;
        set;
    }
}

Note how two different group names are used, and how this results in different pivot items being created in the options page. Also note that the display order rearranges the properties in the page even though in code they're still in the same declaration order:

walkthrough02.png walkthrough03.png

Of course the user can still enter bogus email addresses, and no confirmation is required if they turn off that great feature. We'll work on that in a second.

Enum configuration

For enums, the ListPicker control is used. Since enum names can be quite meaningless to the user you have the possibility to change their appearance in the options dialog too. For this you should use the default DescriptionAttribute of the System.ComponentModel namespace that is meant for things like these:

using System.ComponentModel;

// [...]

public enum FeatureChoice
{
    [Description("The first flavor")]
    One,
    [Description("Flavor number two")]
    Two,
    [Description("Last but not least")]
    Three
}

This will result in nicely formatted enum lookup values for the ListPicker:

walkthrough04.png

Special features

Most of the supported data types have built-in additional features, for example minimum/maximum value checks for numeric values, specifying an input scope for the SIP keyboard in case of string values, or-what we need in our case-confirmation prompts when the user tries to change them. The boolean option type allows you to add prompts to have the user confirm a decision, and to provide additional information to them what consequences their choice will have, for example.

[OptionBoolean(DisplayName = "Our greatest feature",
    GroupName = "settings",
    DisplayOrder = 0,
    UserMustConfirmDeactivation = true,
    DeactivationPrompt = "Are you sure you want to turn this off? You cannot use XYZ anymore without this setting.")]
public bool GreatFeature
{
    get;
    set;
}

With this configuration, you will see that a confirmation prompt will appear, and that the option will only be changed when the user accepts the message.

Validation

As mentioned above, some data types already have built-in support for simple validation checks (min/max etc.). In other cases you are able to do more sophisticated validation. In particular, for string properties you're able to specify a regular expression the user-entered value must satisfy. In case of the email field, a simple check for a valid email address can be performed using the following configuration. Also note how the input scope is set to Email to provide a better user experience, and how the validation error message is defined:

[OptionString(DisplayName = "Your email address",
    Description = "If you provide an email address here, we will send you periodic updates about our products.",
    GroupName = "newsletter",
    RegularExpression = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$",
    InputScopeNameValue = InputScopeNameValue.EmailNameOrAddress,
    ValidationErrorMessage = "Please enter a valid email address.")]
public string EmailAddress
{
    get;
    set;
}

This results in a user experience like this:

walkthrough05.png

Additional configuration

Some general aspects of the options page can be configured by using an overload of the Show method that takes an OptionsConfiguration instance. That way you can for example influence what the page title will be:

var config = new OptionsConfiguration
                    {
                        PageTitle = "My Options"
                    };

OptionsService.Current.Show(options, config);

Further Topics

After this introduction, you may be interested in the following reads:

Supported data types - a list of all supported data types and their properties
Tombstoning - what to take into account for tombstoning
Localization - how to properly support other languages
Advanced concept: providing custom views - explains how you can change the built-in editors easily
Advanced concept: adding custom data types - explains how to add support for new data types

Last edited Mar 31, 2013 at 5:14 PM by Mister_Goodcat, version 5

Comments

mkrain Dec 15, 2011 at 8:46 PM 
Is there a way to add a range of values for example a list of possible strings that are options? Here's are some examples I have that I use in my settings pages that uses a LoopingSelector in order to display a range of values:

https://skydrive.live.com/?cid=66E5FCB98F941AC7#cid=66E5FCB98F941AC7&id=66E5FCB98F941AC7%21870

https://skydrive.live.com/?cid=66E5FCB98F941AC7#cid=66E5FCB98F941AC7&id=66E5FCB98F941AC7%21873

Here's an example using a Listbox:

https://skydrive.live.com/?cid=66E5FCB98F941AC7#cid=66E5FCB98F941AC7&id=66E5FCB98F941AC7%21871

Also is there a way to exclude certain properties on a base class object?