What Singleton Pattern is in C# and its implementation

In another post I discussed how to implement Inversion of Control Pattern in C#. In this post I should explain what a singleton is.

The singleton pattern is one of the best-known patterns in software engineering. Essentially, a singleton is a class which only allows a single instance of itself to be created and usually gives simple access to that instance. Most commonly, singletons don't allow any parameters to be specified when creating the instance - as otherwise, a second request for an instance but with a different parameter could be problematic.

There are various different ways of implementing the singleton pattern in C#. I shall present them here in reverse order of elegance, starting with the most commonly seen, which is not thread-safe, and working up to a fully lazily-loaded, thread-safe, simple and highly performant version.

All these implementations share four common characteristics, however:

  • A single constructor, which is private and parameterless. This prevents other classes from instantiating it (which would be a violation of the pattern). Note that it also prevents subclassing - if a singleton can be subclassed once, it can be subclassed twice, and if each of those subclasses can create an instance, the pattern is violated. The factory pattern can be used if you need a single instance of a base type, but the exact type isn't known until runtime.
  • The class is sealed. This is unnecessary, strictly speaking, due to the above point, but may help the JIT to optimise things more.
  • A static variable which holds a reference to the single created instance, if any.
  • A public static means of getting the reference to the single created instance, creating one if necessary.

First version - not thread-safe

// Bad code! Do not use!
public sealed class Singleton
{
    private static Singleton instance=null;

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (instance==null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}

As hinted at before, the above is not thread-safe. Two different threads could both have evaluated the test if (instance==null) and found it to be true, then both create instances, which violates the singleton pattern. Note that in fact the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.

Second version - simple thread-safety

public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }
}

This implementation is thread-safe. The thread takes out a lock on a shared object and then checks whether or not the instance has been created before creating the instance. This takes care of the memory barrier issue (as locking makes sure that all reads occur logically after the lock acquire, and unlocking makes sure that all writes occur logically before the lock release) and ensures that only one thread will create an instance (as only one thread can be in that part of the code at a time - by the time the second thread enters it, the first thread will have created the instance, so the expression will evaluate to false). Unfortunately, performance suffers as a lock is acquired every time the instance is requested.

Note that instead of locking on typeof(Singleton) as some versions of this implementation do, I lock on the value of a static variable which is private to the class. Locking on objects which other classes can access and lock on (such as the type) risks performance issues and even deadlocks. This is a general style preference of mine - wherever possible, only lock on objects specifically created for the purpose of locking, or which document that they are to be locked on for specific purposes (e.g. for waiting/pulsing a queue). Usually, such objects should be private to the class they are used in. This helps to make writing thread-safe applications significantly easier.

Third version - attempted thread-safety using double-check locking

// Bad code! Do not use!
public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}

This implementation attempts to be thread-safe without the necessity of taking out a lock every time. Unfortunately, there are four downsides to the pattern:

  • It doesn't work in Java. This may seem an odd thing to comment on, but it's worth knowing if you ever need the singleton pattern in Java, and C# programmers may well also be Java programmers. The Java memory model doesn't ensure that the constructor completes before the reference to the new object is assigned to the instance. The Java memory model underwent a reworking for version 1.5, but double-check locking is still broken after this without a volatile variable (as in C#).
  • Without any memory barriers, it's broken in the ECMA CLI specification too. It's possible that under the .NET 2.0 memory model (which is stronger than the ECMA spec) it's safe, but I'd rather not rely on that stronger semantics, especially if there's any doubt as to the safety. Making the instance variable volatile can make it work, as would explicit memory barrier calls, although in the latter case even experts can't agree exactly which barriers are required. I tend to try to avoid situations where experts don't agree what's right and what's wrong!
  • It's easy to get wrong. The pattern needs to be pretty much exactly as above - any significant changes are likely to impact either performance or correctness.
  • It still doesn't perform as well as the later implementations.

Fourth version - not quite as lazy, but thread-safe without using locks

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

As you can see, this is really is extremely simple - but why is it thread-safe and how lazy is it? Static constructors in C# are specified to execute only when an instance of the class is created or a static member is referenced, and to execute only once per AppDomain. Given that this check for the type being newly constructed needs to be executed whatever else happens, it will be faster than adding extra checking as in the previous examples. There are a couple of wrinkles, however:

  • It's not as lazy as the other implementations. In particular, if you have static members other than Instance, the first reference to those members will involve creating the instance. This is corrected in the next implementation.
  • There are complications if one static constructor invokes another which invokes the first again. Look in the .NET specifications for more details about the exact nature of type initializers - they're unlikely to bite you, but it's worth being aware of the consequences of static constructors which refer to each other in a cycle.
  • The laziness of type initializers is only guaranteed by .NET when the type isn't marked with a special flag called beforefieldinit. Unfortunately, the C# compiler (as provided in the .NET 1.1 runtime, at least) marks all types which don't have a static constructor (i.e. a block which looks like a constructor but is marked static) as beforefieldinit.

One shortcut you can take with this implementation (and only this one) is to just make instance a public static readonly variable, and get rid of the property entirely. This makes the basic skeleton code absolutely tiny! Many people, however, prefer to have a property in case further action is needed in future, and JIT inlining is likely to make the performance identical.

Fifth version - fully lazy instantiation

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }
        
    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

Here, instantiation is triggered by the first reference to the static member of the nested class, which only occurs in Instance. This means the implementation is fully lazy but has all the performance benefits of the previous ones. Note that although nested classes have access to the enclosing class's private members, the reverse is not true, hence the need for instance to be internal here. That doesn't raise any other problems, though, as the class itself is private. The code is a bit more complicated in order to make the instantiation lazy, however.

Sixth version - using .NET 4's Lazy<T> type

If you're using .NET 4 (or higher), you can use the System.Lazy type to make the laziness really simple. All you need to do is pass a delegate to the constructor which calls the Singleton constructor - which is done most easily with a lambda expression.

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());
    
    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

It's simple and performs well. It also allows you to check whether or not the instance has been created yet with the IsValueCreated property if you need that.

Structural code in C#

This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class can be created.

using System;

namespace PSC.Singleton
{
    class Program
    {
        /// <summary>
        /// MainApp startup class for Structural
        /// Singleton Design Pattern.
        /// </summary>
        static void Main(string[] args)
        {
            // Constructor is protected -- cannot use new
            Singleton s1 = Singleton.Instance();
            Singleton s2 = Singleton.Instance();

            // Test for same instance
            if (s1 == s2)
            {
                Console.WriteLine("Objects are the same instance");
            }

            // Wait for user
            Console.ReadKey();
        }

        /// <summary>
        /// The 'Singleton' class
        /// </summary>
        class Singleton
        {
            private static Singleton _instance;

            // Constructor is 'protected'
            protected Singleton()
            {
            }

            public static Singleton Instance()
            {
                // Uses lazy initialization.
                // Note: this is not thread safe.
                if (_instance == null)
                {
                    _instance = new Singleton();
                }

                return _instance;
            }
        }
    }
}

Real-world code in C#

This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go through the one object that has knowledge about the state of the (web) farm.

using System;
using System.Collections.Generic;

namespace PSC.Singleton
{
    class Program
    {
        /// <summary>
        /// MainApp startup class for Structural
        /// Singleton Design Pattern.
        /// </summary>
        static void Main(string[] args)
        {
            LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

            // Same instance?
            if (b1 == b2 && b2 == b3 && b3 == b4)
            {
                Console.WriteLine("Same instance\n");
            }

            // Load balance 15 server requests
            LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
            for (int i = 0; i < 15; i++)
            {
                string server = balancer.Server;
                Console.WriteLine("Dispatch Request to: " + server);
            }

            // Wait for user
            Console.ReadKey();
        }

        /// <summary>
        /// The 'Singleton' class
        /// </summary>
        class LoadBalancer
        {
            private static LoadBalancer _instance;
            private List<string> _servers = new Listlt;string>();
            private Random _random = new Random();

            // Lock synchronization object
            private static object syncLock = new object();

            // Constructor (protected)
            protected LoadBalancer()
            {
                // List of available servers
                _servers.Add("ServerI");
                _servers.Add("ServerII");
                _servers.Add("ServerIII");
                _servers.Add("ServerIV");
                _servers.Add("ServerV");
            }

            public static LoadBalancer GetLoadBalancer()
            {
                // Support multithreaded applications through
                // 'Double checked locking' pattern which (once
                // the instance exists) avoids locking each
                // time the method is invoked
                if (_instance == null)
                {
                    lock (syncLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new LoadBalancer();
                        }
                    }
                }

                return _instance;
            }

            // Simple, but effective random load balancer
            public string Server
            {
                get
                {
                    int r = _random.Next(_servers.Count);
                    return _servers[r].ToString();
                }
            }
        }
    }
}

Singleton real-world output

How To Append 'st', 'nd', 'rd' or 'th' To Day Numbers in Dates

For a new project, my client required to output date strings in a format that included the two letter suffix added to the day number, like in British date ("January 1st 2018" as opposed to "January 1 2018").

The solution makes use of the custom formatting capabilities in the framework whereby it is possible to implement the IFormatProvider and ICustomFormatter interfaces to provide custom string formatting for use with methods that support formatting such as String.Format() or Console.WriteLine().

I decided to extend the existing DateTime format provision in the framework by adding new format options for the DateTime type.

StandardExampleWith suffixExample
dd31ddx31st
D31 January 2008Dx31st January 2008
F31 January 2008 21:30:15Fx31st January 2008 21:30:15
f31 January 2008 21:30fx31st January 2008 21:30
m31 Januarymx31st January
RThu, 31 Jan 2008 21:30:15 GMTRxThu, 31st Jan 2008 21:30:15 GMT
U31 January 2008 21:30:15Ux31st January 2008 21:30:15
--xst

The result code is:

namespace PSC.Extensions
{
    /// <summary>
    /// Custom Formatter for providing suffix text for day numbers 
    /// (e.g. "1st", "22nd", "14th", etc.)
    /// 
    /// Example:
    /// string str = string.Format(new DayNumberFormatInfo(), 
    ///                            "{0:Dx}", DateTime.Now);
    /// </summary>
    public sealed class DayNumberFormatInfo : IFormatProvider, ICustomFormatter
    {
        #region IFormatProvider Members
        /// <summary>
        /// IFormat provider
        /// </summary>
        /// <returns>IFormatProvider</returns>
        /// <param name="formatType">Format type.</param>
        object IFormatProvider.GetFormat(Type formatType)
        {
            if (typeof(ICustomFormatter).Equals(formatType))
                return this;
            else
                return null;
        }
        #endregion
        #region ICustomFormatter Members
        /// <summary>
        /// ICustomFormatter
        /// </summary>
        /// <returns>ICustomFormatter</returns>
        /// <param name="format">Format.</param>
        /// <param name="arg">Argument.</param>
        /// <param name="formatProvider">Format provider.</param>
        string ICustomFormatter.Format(string format, object arg, 
                                       IFormatProvider formatProvider)
        {
            // If this is a DateTime with a supported format string...
            if (!string.IsNullOrEmpty(format) && arg is DateTime)
            {
                DateTime dateTime = (DateTime)arg;
                string formatString = format.Trim();

                if (formatString.Equals("Dx", StringComparison.Ordinal))
                    return string.Format(formatProvider, 
                                        "{1} {0:MMMM} {0:yyyy}", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));

                else if (formatString.Equals("Mx", StringComparison.OrdinalIgnoreCase))
                    return string.Format(formatProvider, 
                                         "{1} {0:MMMM}", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));

                else if (formatString.Equals("fx", StringComparison.Ordinal))
                    return string.Format(formatProvider, 
                                         "{1} {0:MMMM} {0:yyyy} {0:t}", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));

                else if (formatString.Equals("Fx", StringComparison.Ordinal))
                    return string.Format(formatProvider, 
                                         "{1} {0:MMMM} {0:yyyy} {0:T}", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));

                else if (formatString.Equals("ddx", StringComparison.Ordinal))
                    return FormatDayNumberSuffix(dateTime);

                else if (formatString.Equals("x", StringComparison.Ordinal))
                    return GetDayNumberSuffix(dateTime);

                else if (formatString.Equals("Rx", StringComparison.OrdinalIgnoreCase))
                    return string.Format(formatProvider, 
                                         "{0:ddd}, {1} {0:MMM} {0:yyyy} {0:T} GMT", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));

                else if (formatString.Equals("Ux", StringComparison.Ordinal))
                    return string.Format(formatProvider, 
                                         "{1} {0:MMMM} {0:yyyy} {0:T}", 
                                         dateTime, 
                                         FormatDayNumberSuffix(dateTime));
            }

            // If it's not a DateTime or has an unsupported format...
            if (arg is IFormattable)
                return ((IFormattable)arg).ToString(format, formatProvider);
            else
                return arg.ToString();
        }
        #endregion
        #region Helpers
        /// <summary>
        /// Returns day number with two character suffix text for the 
        /// day number component in the given date value
        /// </summary>
        /// <param name="date">Date</param>
        /// <returns>String of day number including suffix (1st, 2nd, 3rd, 4th etc.)</returns>
        private static string FormatDayNumberSuffix(DateTime date)
        {
            if (date == null)
                throw new ArgumentNullException(nameof(date));

            return string.Format(CultureInfo.InvariantCulture, "{0:dd}{1}", 
                                 date, GetDayNumberSuffix(date));
        }

        /// <summary>
        /// Returns just the two character suffix text for the 
        /// day number component in the given date value
        /// </summary>
        /// <param name="date">Date</param>
        /// <returns>String of day number suffix (st, nd, rd or th)</returns>
        private static string GetDayNumberSuffix(DateTime date)
        {
            if (date == null)
                throw new ArgumentNullException(nameof(date));

            int day = date.Day;

            switch (day)
            {
                case 1:
                case 21:
                case 31:
                    return "st";

                case 2:
                case 22:
                    return "nd";

                case 3:
                case 23:
                    return "rd";

                default:
                    return "th";
            }
        }
        #endregion
    }
}

Xamarin Forms: TranslateY (or other properties) for platform

Sometimes you need to change a value for a specific platform and this value is a Double, for example. I spent a couple of minutes to find a working code.

<Label>
    <Label.TranslationY>
        <OnPlatform x:TypeArguments="x:Double" Android="-10" />
    </Label.TranslationY>
</Label>

Happy coding!

The Invoke Smart Speaker Brings Microsoft’s Cortana AI to Your Living Room

Invoke-Cortana

Cortana virtual assistant already integrates into Windows 10, works on iOS and Android, and will start showing up in cars soon, it’s ready for your home with Invoke. It's good for work, good for play, even has a cool name.

The new Invoke speaker, made by Harman Kardon, is more or less a direct copy of the Amazon Echo - a tall, cylindrical speaker with a blue light at the top that glows when the speaker is listening to you. It can control some of your smart-home devices, set reminders, name the members of One Direction (RIP), and many other things Echo can also do. So far, the Invoke appears to have exactly one unique feature: It can make and receive calls with Skype.

Enable and control iOS 11 Large Titles in Xamarin.Forms

Apple introduced with iOS 11 a new UI in particular for larger titles: if you open your email, you see at the top a large title. That sit in the Navigation Bar and can be scrolled away when more space is needed. We can enable large titles with a renderer.

For this example, I only created a new project and added the following renderer in the iOS project under Renderers folder. You can easily add to all your solution the following renderer in your iOS project:

using System;
using YourProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(NavigationPage), 
                          typeof(CustomNavigationRenderer))]
namespace YourProject.iOS.Renderers
{
    public class CustomNavigationRenderer : NavigationRenderer
    {
        protected override void OnElementChanged(
                                VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            // Enables iOS 11 new Large Titles system-wide
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                // Enable Large Titles
                NavigationBar.PrefersLargeTitles = true;

                // Adopt same TextAttributes as for normal titles
                // beacuse Xamarin.Forms NavigationPage
                // does not have a dedicated property for this yet
                UINavigationBar.Appearance.LargeTitleTextAttributes =
                    new UIStringAttributes { 
                            ForegroundColor = 
                               (Element as NavigationPage)?.
                               BarTextColor.ToUIColor() };
            }
        }
    }
}

iOS 8 Screenshot - Large title

Happy coding!

UriBuilder in Xamarin Forms

In Xamarin Forms there is a native function called UriBuilder: it allow you to create a well-formed url. In my implementation, all parameters are in a Dictionary called parameters. Using Linq, I put in builder.Query only the parameters with a value.

UriBuilder builder = new UriBuilder(yourUrl);

Dictionary<string, string> parameters = 
                              new Dictionary<string, string>();
parameters.Add("reference", Reference);
parameters.Add("param1", Param1);

builder.Query = 
    string.Join("&", 
        parameters.Where(p => !string.IsNullOrWhiteSpace(p.Value))
                  .Select(p => string.Format("{0}={1}", 
                                      Uri.EscapeDataString(p.Key), 
                                      Uri.EscapeDataString(p.Value))));
return builder.ToString();

Happy coding!

Microsoft release new XAML Controls Gallery app to help developers implement Fluent Design

xalm-controls-gallery

Microsoft is hoping developers will be updating their UWP apps en masse to support their new Fluent Design language, and to help them along Microsoft has published an app in the store that demonstrates all the controls available.

XAML Controls Gallery” demonstrates all of the controls available in Fluent Design System and XAML. It’s the interactive companion to the Fluent Design System web site which can be seen here.

According to Microsoft, the new Microsoft Fluent Design System will deliver “intuitive, harmonious, responsive and inclusive cross-device experiences and interactions” for users. As for developers, the Microsoft Fluent Design System will allow them to deliver engaging experiences that work across a wide range of devices with input diversity.

The source code to the app is available on Github here and developers can download the app from the Store here.

Binding FormattedString for Xamarin Forms

Xamarin Forms doesn't have a Label with a Bindable FormattedString. For example, if you want a bindable bold word in the middle of a sentence in a Label, it's very hard to design it with common control. For that, I create my own component for that.

LabelRenderer.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace PSC.Controls
{
    public class Label : Xamarin.Forms.Label
    {
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            UpdateFormattedTextBindingContext();
        }

        protected override void OnPropertyChanged(
           [CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == FormattedTextProperty.PropertyName)
                UpdateFormattedTextBindingContext();
        }

        private void UpdateFormattedTextBindingContext()
        {
            var formattedText = this.FormattedText as FormattedString;

            if (formattedText == null)
                return;

            foreach (var span in formattedText.BindableSpans)
                span.BindingContext = this.BindingContext;
        }
    }

    [ContentProperty("BindableSpans")]
    public class FormattedString : Xamarin.Forms.FormattedString
    {
        private ObservableCollection<Span> _bindableSpans = 
            new ObservableCollection<Span>();

        public IList<Span> BindableSpans { 
            get { return this._bindableSpans; } 
        }

        public FormattedString()
        {
            this._bindableSpans.CollectionChanged += OnCollectionChanged;
        }

        private void OnCollectionChanged(object sender, 
            NotifyCollectionChangedEventArgs e)
        {
            if (e.OldItems != null)
            {
                foreach (var bindableSpan in e.OldItems.Cast<Span>())
                    base.Spans.Remove(bindableSpan);
            }
            if (e.NewItems != null)
            {
                foreach (var bindableSpan in e.NewItems.Cast<Span>())
                    base.Spans.Add(bindableSpan);
            }
        }

        /// <param name="text">To be added.</param>
        /// <summary>
        /// Cast a string to a FromattedString that contains 
        /// a single span with no attribute set.
        /// </summary>
        /// <returns>To be added.</returns>
        public static implicit operator FormattedString(string text)
        {
            return new FormattedString
            {
                BindableSpans = { 
                    new Span { Text = text ?? "" } 
                }
            };
        }
        /// <param name="formatted">To be added.</param>
        /// <summary>
        /// Cast the FormattedString to a string, 
        /// stripping all the attributes.
        /// </summary>
        /// <returns>To be added.</returns>
        public static explicit operator string(FormattedString formatted)
        {
            return formatted.ToString();
        }
    }

    [ContentProperty("Text")]
    public sealed class Span : BindableObject
    {
        Xamarin.Forms.Span _innerSpan;

        public Span() : this(new Xamarin.Forms.Span()) { }

        public Span(Xamarin.Forms.Span span)
        {
            _innerSpan = span;
            // important for triggering property inheritance from parent Label
            this.BackgroundColor = this._innerSpan.BackgroundColor;
            this.FontSize = this._innerSpan.FontSize;
            this.FontAttributes = this._innerSpan.FontAttributes;
            this.FontFamily = this._innerSpan.FontFamily;
            this.ForegroundColor = this._innerSpan.ForegroundColor;
            this.Text = this._innerSpan.Text ?? "";
        }
        public static readonly BindableProperty BackgroundColorProperty =
            BindableProperty.Create(nameof(BackgroundColor), 
                typeof(Color), typeof(Span), Color.Default);

        public Color BackgroundColor
        {
            get { return (Color)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }

        public static readonly BindableProperty FontAttributesProperty =
            BindableProperty.Create(nameof(FontAttributes), 
                typeof(FontAttributes), 
                typeof(Span), 
                FontAttributes.None);

        public FontAttributes FontAttributes
        {
            get { return (FontAttributes)GetValue(FontAttributesProperty); }
            set { SetValue(FontAttributesProperty, value); }
        }

        public static readonly BindableProperty FontFamilyProperty =
            BindableProperty.Create(nameof(FontFamily), 
                typeof(string), 
                typeof(Span), 
                string.Empty);

        public string FontFamily
        {
            get { return (string)GetValue(FontFamilyProperty); }
            set { SetValue(FontFamilyProperty, value); }
        }

        public static readonly BindableProperty FontSizeProperty =
            BindableProperty.Create(nameof(FontSize), 
                typeof(double), 
                typeof(Span), -1.0, BindingMode.OneWay, 
                null, null, null, null, 
                bindable => Device.GetNamedSize(
                    NamedSize.Default, typeof(Label)));

        [TypeConverter(typeof(FontSizeConverter))]
        public double FontSize
        {
            get { return (double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }

        public static readonly BindableProperty 
            ForegroundColorProperty =
                BindableProperty.Create(nameof(ForegroundColor), 
                   typeof(Color), 
                   typeof(Span), 
                   Color.Default);

        public Color ForegroundColor
        {
            get { return (Color)GetValue(ForegroundColorProperty); }
            set { SetValue(ForegroundColorProperty, value); }
        }

        public static readonly BindableProperty TextProperty =
            BindableProperty.Create(nameof(Text), 
                                    typeof(string), 
                                    typeof(Span), 
                                    string.Empty);

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public Xamarin.Forms.Span InnerSpan { 
            get { return _innerSpan; } 
        }

        protected override void OnPropertyChanged(
            [CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            _innerSpan.BackgroundColor = this.BackgroundColor;
            _innerSpan.FontSize = this.FontSize;
            _innerSpan.FontAttributes = this.FontAttributes;
            _innerSpan.FontFamily = this.FontFamily;
            _innerSpan.ForegroundColor = this.ForegroundColor;
            _innerSpan.Text = this.Text ?? "";
        }

        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
        }

        public static implicit operator Xamarin.Forms.Span(Span bindableSpan)
        {
            return bindableSpan.InnerSpan;
        }

        public static implicit operator Span(
            Xamarin.Forms.Span span)
        {
            return new Span(span);
        }
    }
}

In your XAML you use this control like that:

<ctl:Label
    FontSize="Small"
    TextColor="#333"
    HorizontalOptions="FillAndExpand">
    <Label.FormattedText>
        <ctl:FormattedString>
            <ctl:Span Text="{Binding YourVar1}" FontAttributes="Bold"/>
            <ctl:Span Text="{Binding YourVar2, StringFormat=' {0}'}"/>
        </ctl:FormattedString>
    </Label.FormattedText>
</ctl:Label>

Download the code from GitHub.

Happy coding!

Microsoft Launcher review: A beautiful Android experience

Microsoft-Launcher-with-Surface

After Microsoft gives up on Windows 10 Mobile, Microsoft Launcher is the upgraded version of the Microsoft Garage project Arrow Launcher, and we covered the key changes that came with that upgrade last week. It's free and can be picked up from the Google Play Store.

After some heavy usage over the last few days, we're breaking down what works, what doesn't, and where Microsoft should take their launcher from here.

As Microsoft Launcher gains more publicity, there have been some rumblings about how it doesn't look like Windows 10 Mobile. It's important to point out that it doesn't seem to be the goal of Microsoft to make Android look exactly like Windows 10 Mobile. For example, you won't find Live Tiles anywhere in the launcher. If you're looking for as close to a facsimile of Windows 10 Mobile on Android as possible, there are other options, such as Squarehome 2.

But this isn't a bad thing. Microsoft isn't trying to turn Android into Windows 10 Mobile, they are trying to integrate Microsoft services into the Android experience while also adding some design elements that will be familiar to Windows users. And in that respect, Microsoft Launcher is phenomenal.

For example, there's also an option for a transparent theme. With all the transparent design elements coming in the Windows 10 Fall Creators Update, having a glass effect throughout all of your devices helps them feel more like siblings. Microsoft Launcher's transparency is found on every page in the launcher, including your newsfeed, calendar, people section, and more.

Microsoft-Launcher-Microsoft-Services

Arrow Launcher already had features such as Wunderlist and Outlook calendar integration. Microsoft Launcher takes that idea further by bringing "Continue on PC" to Android. This lets you start doing things on your phone and easily jump to another device. This will be familiar to anyone who has taken advantage of Project Rome. It's a nice addition to Android and will hopefully get better over time. You can take a document you're working on and push it over to your PC. It also works with links, even if you're browsing on Chrome on your phone and have Edge as the default browser on PC. It works fairly well, though it can take a couple seconds to open on your PC.

Microsoft gives up on Windows 10 Mobile

Belfiore_window10_mobile

The company's Windows 10 chief has tweeted that developing new features and hardware for the Mobile version of the OS was no longer a "focus".

Joe Belfiore added that he had also switched to Android himself.

Windows 10 Mobile tried to attract users by letting them run the same "universal apps" on both their PCs and handsets, but the concept failed to catch on.

The OS accounted for just 0.03% of the global market - based on smartphone shipments - between April and June, according to research company IDC.

The market intelligence provider said the news had been a long time coming.

"There wasn't a wide range of devices running Windows 10 Mobile, so it wasn't attractive to retailers or operators," said IDC's Francisco Jeronimo.

"And from a consumer perspective, the operating system didn't provide as good an experience as Android or iOS."

Mr Belfiore began a series of tweets on Sunday by discussing the recent launch of a test version of Microsoft's Edge web browser for Android and iOS - the latest in a series of releases of its core software for rival mobile platforms.

He then went on to respond to questions about whether there was any point sticking with Windows 10 Mobile.

He said that while Microsoft would support the "many companies" that had adopted the platform, he had switched to Android for the diversity of its apps and hardware.

"Of course we'll continue to support the platform... bug fixes, security updates, et cetera," he said.

"But building new features or hardware is not the focus."

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  December 2017  >>
MonTueWedThuFriSatSun
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

View posts in large calendar

Month List