Settings - James Montemagno https://staging.montemagno.com/tag/settings/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png Settings - James Montemagno https://staging.montemagno.com/tag/settings/ Hugo -- gohugo.io Tue, 13 Oct 2026 23:21:57 GMT 60 DataBinding Settings in Xamarin.Forms https://staging.montemagno.com/databinding-settings-in-xamarinforms/ 598df8f2c121b60019bf2ffb Wed, 07 Oct 2015 15:12:02 GMT For nearly four years now I have been using my cross-platform settings plugin to save preferences across all the different platforms. Ever since I pushed it up to NuGet it has been extremely popular with over 18,000 installs! The plugin gives you a very simple way of saving out native settings from shared code. Usually, you will create a native UI for each platform and in the case of Android use the PreferenceActivity to automagically create a settings page from XML (which is magical), but what if you are using Xamarin.Forms and want to databind stuff up? This is the exact question I got over on StackOverflow. Of cource you can, let’s do it.

Given this Settings Class:

public static class Settings
{

    private static ISettings AppSettings
    {
        get
        {
            return CrossSettings.Current;
        }
    }

    const string CountKey = "count";
    private static readonly int CountDefault = 0;

    public static int Count
    {
        get { return AppSettings.GetValueOrDefault(CountKey, CountDefault); }
        set { AppSettings.AddOrUpdateValue(CountKey, value); }
    }
}

Approach 1: Essentially you need to create a view model with a public property that you wish to data bind to and then call into settings from there and raise a property changed notification if the value changed. Your Settings.cs can stay the same but you will need to create the viewmodel such as:

public class MyViewModel : INotifyPropertyChanged
{

    public int Count
    {
        get { return Settings.Count; }
        set
        {
            if (Settings.Count == value)
                return;

            Settings.Count = value;
            OnPropertyChanged();
        }

    }

    private Command increase;
    public Command IncreaseCommand
    {
        get
        {
            return increase ?? (increase = new Command(() => Count++));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName]string name = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;
        changed(this, new PropertyChangedEventArgs(name));
    }

}

Then you XAML will look like this inside your Content page:

<StackLayout Padding="25">
 <Button Text="Increase" Command="{Binding IncreaseCommand}"/>
 <Label Text="{Binding Count, StringFormat='The count is {0:F0}'}"/>
</StackLayout>

Make sure you set the BindingContext in the xaml.cs of the page:

public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();
        BindingContext = new MyViewModel();
    }
}

This actually isn’t too much code to actually implement as your ViewModel would have a BaseViewModel that implements INotifyPropertyChanged, so really you are just adding in

public int Count
{
    get { return Settings.Count; }
    set
    {
        if (Settings.Count == value)
            return;

        Settings.Count = value;
        OnPropertyChanged();
    }
}

Approach 2: More magical way

However, using the powers of C# and knowing how Databinding works you could first create a BaseViewModel that everything will use:

public class BaseViewModel : INotifyPropertyChanged
{
    public Settings Settings
    {
        get { return Settings.Current; }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName]string name = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;
        changed(this, new PropertyChangedEventArgs(name));
    }
}

Notice my reference to Settings.Current, we will need to implement that now as a singleton, but we will use our BaseViewModel so we don’t have to re-implement INotifyPropertyChanged:

public class Settings : BaseViewModel
{
    static ISettings AppSettings
    {
        get
        {
            return CrossSettings.Current;
        }
    }

    static Settings settings;
    public static Settings Current
    {
        get { return settings ?? (settings = new Settings()); }
    }

    const string CountKey = "count";
    static readonly int CountDefault = 0;

    public int Count
    {
        get
        {
            return AppSettings.GetValueOrDefault(CountKey, CountDefault);
        }
        set
        {
            if (AppSettings.AddOrUpdateValue(CountKey, value))
                OnPropertyChanged();

        }
    }
}

Now of course we will still want to create a unique ViewModel that our XAML view will bind to:

public class MyViewModel : BaseViewModel
{
    private Command increase;
    public Command IncreaseCommand
    {
        get
        {
            return increase ?? (increase = new Command(() => Settings.Count++));
        }
    }
}

Notice that we are now inheriting from BaseViewModel, which means our command can actually just increment Settings.Count! But now we must adjust our Xaml just a bit as to what we are actually data binding to for our label:

<StackLayout Padding="25">
 <Button Text="Increase" Command="{Binding IncreaseCommand}"/>
 <Label BindingContext="{Binding Settings}" Text="{Binding Count, StringFormat='The count is {0:F0}'}"/>
</StackLayout>

Notice I am setting the BindingContext to our Settings, which is in our BaseViewModel for the Label, this must be done because that is where it is located now. And there you have it.

]]>
An Improved Cross-Platform Settings Library for iOS, Android, and Windows https://staging.montemagno.com/an-improved-cross-platform-settings-library-for/ 598df8f2c121b60019bf3020 Tue, 18 Nov 2014 19:14:23 GMT If you follow me at all on GitHub or Twitter than you probably know that I love portable class libraries. I know this might sound odd, but I also love settings inside of mobile applications. NSUserDefault, SharedPreferences, IsolatedStorage… yup I love it. A few years back when I was doing a lot of MVVMCross development I created Mvx.Plugins.Settings to enable developers to save settings and preferences extremely easily from 1 common API. Under the hood though I am taking advantage of each platforms native method of saving and retrieving settings. To me this is the best approach especially on Android where you can create an entire settings screen from an XML file!

Settings Everywhere

Back in March, I updated my settings plugin to be completely generic from any framework. This means anyone can use it no matter if you are developing with traditional Xamarin, Xamarin.Forms, or MVVMCross. Today, I am pleased to announce a brand new update, 1.4.0.0, that brings a flurry of enhancements and fixes.

Enhancements

Over the last several months I have added support for Windows 8.1 and Windows Phone 8.1 RT development and in this latest version I bring full support for Xamarin.iOS Unified projects.

Simplified API

I have received a lot of feedback over the year on how the API worked. The biggest issue was that I enforced that you first attempt to “Update” the setting and then call “Save” to actually store the value. This is nice if you wanted to do batch saving of settings, however it was very annoying and created extra code. I have listened and created an even easier API:

There you have it, simply get and set from the settings and the library will handle the rest for you.

Data Types

I have also expanded the datatypes that you can store:

  • Boolean
  • Int32
  • Int64
  • String
  • Single(float)
  • Guid
  • Double
  • Decimal
  • DateTime

Bullet Proof

In addition to all of these enhancements I wanted to make sure that going forward anyone would be able to pull down the library, make changes, and do a full regression test. I have built out a full NUnit test library to ensure the highest quality for the library.

Get it today

As always you can get the entire source code on the GitHub project where you can contribute to the project. Additionally, you can get the NuGet today.

]]>