Search code examples
c#xamldata-bindinguwpsingleton

Binding XAML element to Singleton class members


So I'm going off this site: Winsows 10 UWP: How to Read and Save Setting Easily - Edi.Wang

I tried using

 <Page.Resources>
    <core:AppSettings x:Key="AppSettings"/>
 </Page.Resources>

but I get an error

Type 'AppSettings' is not usable as an object because it is not public or does not define a public parameterless constructor or a type converter.

This is my AppSettings class that I implemented as a singleton, where the one given in the example is not.

using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.Storage;

namespace MediaManager.Services
{
    /// <summary>
    /// Singleton class for handing application settings data.
    /// </summary>
    public class AppSettings : INotifyPropertyChanged
    {
        private static volatile AppSettings _instance;

        private ApplicationDataContainer _localData = null;
        private ApplicationDataContainer _roamingData = null;

        private static object syncRoot = new object();

        private AppSettings()
        {
            _localData = ApplicationData.Current.LocalSettings;
            _roamingData = ApplicationData.Current.RoamingSettings;
        }

        public static AppSettings Instance
        {
            get
            {
                if (_instance is null)
                    lock (syncRoot)
                        if (_instance is null)
                            _instance = new AppSettings();

                return _instance;
            }
        }

        private void SaveSettings(string key, object value, bool roaming = false)
        {
            if (roaming)
                _roamingData.Values[key] = value;
            else
                _localData.Values[key] = value;
        }

        private T ReadSetting<T>(string key, T defaultValue = default(T), bool roaming = false)
        {
            if (roaming)
            {
                if (_roamingData.Values.ContainsKey(key))
                    return (T)_localData.Values[key];
            }
            else if (_localData.Values.ContainsKey(key))
                return (T)_localData.Values[key];

            return defaultValue;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged([CallerMemberName]string propName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }

        // List all setting here
        public string movie_staging_folder
        {
            get => ReadSetting<string>(nameof(movie_staging_folder), roaming: true);
            set
            {
                SaveSettings(nameof(movie_staging_folder), value, true);
                NotifyPropertyChanged();
            }
        }
    }
}

I understand that just like the error says, my appSettings.cs has no public constructor; it's a singleton class. I can't figure out how to get the data binding to work with a singleton class.


Solution

  • <TextBlock Text="{x:Bind local:AppSettings.Instance.MySetting, Mode=OneWay}" />
    
    public class AppSettings
    {
        private AppSettings()
        {
        }
    
        public static AppSettings Instance { get; } = new AppSettings();
    
        public string MySetting => "My setting";
    }