One of the things that distinguishes great Windows Phone applications is the ability to configure to the preferences of the user. Let’s pretend the user wants to enable or disable a feature – how do they do that?
The best way to provide this custom experience is through a settings page. In this article we will create a reusable setting framework you can use in all your Windows Phone applications.
Note: This is going to be one of the those blog posts that is just freaking handy. Every single application (practically) needs to do this. And without explicit guidance anywhere else, it will be nice to have something to base your solution. I’m not saying this is the only way, but it’s a great way.
(Let’s get nerdy for a second) The nature of your configurability is going to be driven by your creativity as the developer and the nature of your application. However, there are some interesting terms to consider – and would be nice to get correct.
What we are talking about in this article is customization. Customization is the ability for an application to allow the current user to tailor the features and feel to their preferences.
Techspot: Customization centers around what resources (portlets and pages) you show the users based on their role [or preferences]. This is a core capability of Portal. There are tools provided that help administrators provision these resources. Typically, portlets allow users to specify what kind of information should display. For example, a weather portlet might be customized to show
weather in the users home town.
The best example of this is in Windows. Specifically, the Widows Control Panel. Here, the user can turn on and off features of the Operating System based on their preferences.
What we are not talking about in this article, but could easily be implemented with similar code, is personalization. Personalization takes existing features or information and tailors their content to the current user.
Wikipedia: Personalization involves using technology to accommodate the differences between individuals. Once confined mainly to the Web, it is increasingly becoming a factor in education, health care (i.e. personalized medicine), television, and in both "business to business" and "business to consumer" settings.
The best example of this is in Windows. The Windows (desktop) Personalize dialog allows the user to change the background and colors of Windows. This dialog is not where you turn off features, but where the user tailors them to their preferences.
Another example of personalization is news feeds. When the feed is on or off, this is a customization – the user is turning the feature on or off. However, when my news feed starts to show Star Trek news because I love it, and not Star Wars news because it is stupid – that is personalization.
Personalization can be automatic,too. This is adaptation. Adaption is typically accomplished through a type of profiling based on user info or behaviors.
Wikipedia: The term “adaptation” in computer science refers to a process, in which an interactive system (adaptive system) adapts its behaviour to individual users based on information acquired about its user(s) and its environment.
Let’s build it!
In the video below, I will walk you through creating a simple Settings page and implementing it. In 5 minutes, we accomplish a lot so come ready to listen closely.
In the video above, I made a mistake when I called an Event a Property. I would like for all of you to know: I know the difference! Now that that is out of the way, let’s talk about the approach.
Note: You don’t have to use Isolated Storage. Of course this is true. Although, Isolated Storage is very simple and present for this purpose. You might want to use your local database. You might want to use the cloud. Whatever you want to use – this approach remains valid, just update the Get() and Set() methods to fetch and persist to your preferred store.
Those Generic Methods
In the code above, I am creating a public, static property called AllowSave. As you create your settings page, you may not have AllowSave, but you might have PromptToExit, EnableLocationServices, or other things like that. It certainly does not have to be Boolean. Again, this is totally up to you and your application.
The Get() method is generic (see the T?) and you use it to get a value from Isolated Storage (or whatever store you want to use to persist your values). The reason for the try/catch block is because it skips a dozen checks you would otherwise have to do in order to avoid exceptions while retrieving an Isolated Storage value: is the key present? is the value null? does the value cast? and so on.
The Set() method is also generic. It allows you to pass basically anything into it and it will persist it into Isolated Storage (the Isolated Storage settings dictionary will serialize the object for you). Again, remember, since we are reusing these methods, whatever persistence store you end up using will flow to all your properties transparently – it also means you can change your store without changing your properties or the implementations.
Finally, there’s SettingChanged. This is an event – I know. Even though I called it a property in the video, this is an event and it is important. It allows consuming parts of the application to immediately reflect the change in the setting. This is very important because if your settings are not reflected throughout the application, the user will think it does not work, and they will be tempted to test if the UNISTALL feature works – remember, it is us versus the UNISTALL button!
Get the code here.
It would be unusual for an application not to have some type of settings. Settings provide a way to give a user a better experience. To make them love your application more. And to keep them from Uninstalling your application from their phone.
- WP7 Sample: Isolated Storage – for info on using Isolated Storage
- WP7 Sample: Local Database – for info on using a local database
- WP7 Sample: Access the Cloud – for info on using the cloud
- WP7 Sample: Location Services – for another example of settings
Best of luck!