Simple example for MongoDB. Save and retrieve data from Azure Cosmos DB.
Create an Azure Cosmos Db as MongoDb
For creating a new MongoDb on Azure, search from the list of resources, Azure Cosmos Db. Then Add a new database and you see the following screen.

Overview
When you created a new MongoDb, you see an Overview where there are general information about how many queries the database did (split on insert, update, cancel, query, count, others).

Under Connection String you have the connection to use in your application. In this project you insert in Program.cs the connection string in the variable called connectionString.
DataExplorer
You can explorer all data in your Mongo database. Click on Data Explorer and you can see everything. Also, you can execute same queries.

You find an example application on my GitHub.
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();
}
}
}
}
}
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.
Standard | Example | With suffix | Example |
---|
dd | 31 | ddx | 31st |
D | 31 January 2008 | Dx | 31st January 2008 |
F | 31 January 2008 21:30:15 | Fx | 31st January 2008 21:30:15 |
f | 31 January 2008 21:30 | fx | 31st January 2008 21:30 |
m | 31 January | mx | 31st January |
R | Thu, 31 Jan 2008 21:30:15 GMT | Rx | Thu, 31st Jan 2008 21:30:15 GMT |
U | 31 January 2008 21:30:15 | Ux | 31st January 2008 21:30:15 |
- | - | x | st |
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
}
}
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!
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() };
}
}
}
}
Happy coding!
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!
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!
A ListView is a kind of repeater but isn’t always what I want. It’s surprising something like this isn’t included in the framework but making your own is fairly simple.
namespace PSC.Controls
{
/// <summary>
/// Repeater view.
/// </summary>
public class RepeaterView : StackLayout
{
/// <summary>
/// The item template property.
/// </summary>
public static readonly BindableProperty ItemTemplateProperty =
BindableProperty.Create(
"ItemTemplate",
typeof(DataTemplate),
typeof(RepeaterView),
null,
propertyChanged: (bindable, value, newValue) =>
Populate(bindable));
/// <summary>
/// The items source property.
/// </summary>
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create(
"ItemsSource",
typeof(IEnumerable),
typeof(RepeaterView),
null,
BindingMode.OneWay,
propertyChanged: (bindable, value, newValue) =>
Populate(bindable));
/// <summary>
/// Gets or sets the items source.
/// </summary>
/// <value>The items source.</value>
public IEnumerable ItemsSource
{
get => (IEnumerable)this.GetValue(ItemsSourceProperty);
set => this.SetValue(ItemsSourceProperty, value);
}
/// <summary>
/// Gets or sets the item template.
/// </summary>
/// <value>The item template.</value>
public DataTemplate ItemTemplate
{
get => (DataTemplate)this.GetValue(ItemTemplateProperty);
set => this.SetValue(ItemTemplateProperty, value);
}
/// <summary>
/// Populate the specified bindable.
/// </summary>
/// <returns>The populate.</returns>
/// <param name="bindable">Bindable.</param>
private static void Populate(BindableObject bindable)
{
var repeater = (RepeaterView)bindable;
// Clean
repeater.Children.Clear();
// Only populate once both properties are received
if (repeater.ItemsSource == null ||
repeater.ItemTemplate == null)
return;
foreach (var viewModel in repeater.ItemsSource)
{
var content = repeater.ItemTemplate.CreateContent();
if (!(content is View) && !(content is ViewCell))
{
throw new Exception(
$"Invalid visual object {nameof(content)}");
}
var view = content is View ? content as View :
((ViewCell)content).View;
view.BindingContext = viewModel;
repeater.Children.Add(view);
}
}
}
}
The view is based on StackLayout which will take care of positioning the items.
There are a couple of bindable properties – ItemTemplate for the item layout and ItemsSource which provides the items. Note that ItemsSource hooks an action to PropertyChanging – I’ll come back to this later on.
Usage in XAML is similar to ListView, with an ItemTemplate, DataTemplate, and ViewCell.
<ui:Repeater x:Name="MainRepeater">
<ui:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Title}"
HorizontalOptions="StartAndExpand"
VerticalTextAlignment="Center"/>
<Button Text="Select" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ui:Repeater.ItemTemplate>
</ui:Repeater>
Don't forget to define ui
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ui="clr-namespace:PSC.Controls;assembly=PSC.Controls">
In this post I explain how to use Finger Print in your app. This app is working only in iOS or Android.
Add NuGet
In your solution, you have to add a package called
Plugin.Fingerprint.
Only for Android, in your Droid project add another package called Plugin.CurrentActivity. Also, you have to add a permission for fingerprint (and one specific for Samsung).
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission
android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
Implementation
Now we implement in our PCL project the request for fingerprint. First of all we have to check if a device supports fingerprints. If yes, we show the typical dialog.
Now I added a button in the XAML and its name is buttonFingerPrint. For it in the code behind, I added a Clicked event. Then In the new function, I'm checking is the device supports fingerprint.
var result = await CrossFingerprint.Current.IsAvailableAsync(true);
The function IsAvailableAsync as true as parameter but it is useful only for iOS to have a code in return. If the device supports fingerprint, I'll show a dialog request with this code:
if (result) {
var auth = await CrossFingerprint.Current
.AuthenticateAsync("Authenticate access to fingerprint");
if (auth.Authenticated) {
await DisplayAlert("Whoooowhooo!", "Authentication is done!", "Ok");
}
else {
await DisplayAlert("Something wrong",
"There is a problem with your finger", "Ok");
}
}
else {
await DisplayAlert("Finger print not available",
"You can't use your finger for using this app", "Ok");
}
Testing on an emulator
iOS
If you test your project in an iOS device, be careful to allow to use Touch ID from Hardware menu with Toggle Enrolled State. When you want to test your virtual finger, select Matching Touch.
Android
Let's go to the Android emulator. You need to set up fingerprint under Settings. From your Terminal call (5554 is the default port of an Android emulator but it can be different in your computer)
telnet 127.0.0.1 5554
Then you have to copy an auth token from an hidden file called .emulator_console_auth_token in your profile. In the terminal execute
auth <yourcode>
Now open Settings > Security > Fingerprint and follow the instruction. When you have to recognise your finder, come back to the terminal and type
finger touch 1
Then you can continue with the wizard.
Now you can execute your app. When your app ask your fingerprint, come back to the Terminal and type again
finger touch 1
Android is always easy to use! You find my solution on GitHub.
Happy coding!
In my previous post called Xamarin: how to Start an Application at Device Boot in Android, I explained how you can change your Android Xamarin's project to launch your app at the device boot.
It is a good start but my problem was a bit more complex. I want to create a background service to track the geolocation of a device. I googled a lot to find a solution without a great success. Then I started to implement my code with some tests. Finally, I found a good way and I'm sharing with you it.
Create a Broadcast Receiver
What is a Broadcast Receiver
A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work.
How to implement a Broadcast Receiver
I show you now two implementations of it:
-
BootReceiver: this receiver is responsible to do something when a device starts. For that, we have to allow the app to read this event. In your AndroidManifest.xml you must add a permission called RECEIVE_BOOT_COMPLETED.
-
AirplaneModeReceiver: this receiver filters only the broadcast for ActionAirplaneModeChanged.
I start to show you the second one because it is more simple.
[BroadcastReceiver]
[IntentFilter(new[] { Android.Content.Intent.ActionAirplaneModeChanged })]
public class AirplaneModeReceiver : BroadcastReceiver
{
private static readonly string TAG = typeof(AirplaneModeReceiver).FullName;
public override void OnReceive(Context context, Intent intent)
{
Log.WriteLine(LogPriority.Debug, TAG, "AirplaneModeReceiver OnReceive Mode " +
isAirplaneModeOn(context));
}
private static bool isAirplaneModeOn(Context context)
{
var airplane = Android.Provider.Settings.Global.GetInt(context.ContentResolver,
Android.Provider.Settings.Global.AirplaneModeOn);
return airplane != 0;
}
}
Although you can find a lot of posts where people said that you have to declare your broadcast in the AndroidManifest, I discover if I add the broadcast in the AndroidManifest, the broadcast won't work.
This is the first broadcast. Basically when a user taps on AirPlaneMode, this broadcast receives the status with isAirplaneModeOn function and writes this change in the logs.
BootReceiver is more interesting. When a device is booting, this broadcast starts a service to track the position. Also, in my code you find TimeService: I use this service to check if the service is starting properly and the notification is working and updating.
[BroadcastReceiver]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
private static readonly string TAG = typeof(BootReceiver).FullName;
public override void OnReceive(Context context, Intent intent)
{
Log.WriteLine(LogPriority.Debug, TAG, "BootReceiver OnReceive");
Intent i = new Intent(context, typeof(GPSService));
i.AddFlags(ActivityFlags.NewTask);
context.StartService(i);
Log.WriteLine(LogPriority.Debug, TAG,
"BootReceiver OnReceive LocationService started");
i = new Intent(context, typeof(TimerService));
i.AddFlags(ActivityFlags.NewTask);
context.StartService(i);
Log.WriteLine(LogPriority.Debug, TAG,
"BootReceiver OnReceive TimerService started");
}
}
The interesting part of this code is when I start a service. Basically, I define a new Intent with the type of service I want to call, then I start the service with the context.
Although you find a lot of posts on line, the right way to define a service in your AndroidManifest is the following:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="pro.wordbank.app.locationtest">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="LocationTest">
<service android:name=".TimerService" />
<service android:name=".LocationService" />
</application>
</manifest>
I have publish a complete solution of that on GitHub. Happy coding!