Xamarin.Forms – Implementing ItemsSource for Custom Control

Here’s some code for ItemsSource:

        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
           propertyChanged: (bindable, oldValue, newValue) => OnItemsSourceChanged(bindable, oldValue, newValue));

        static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
            void newValueINotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
                var wraplayout = bindable as WrapLayout;

                if (e.OldItems != null)
                    foreach (var item in e.OldItems)
                        wraplayout.Children.Remove(item as View);

                if (e.NewItems != null)
                    foreach (var item in e.NewItems)
                        wraplayout.Children.Add(item as View);

            var oldValueINotifyCollectionChanged = oldValue as INotifyCollectionChanged;

            if (null != oldValueINotifyCollectionChanged)
                oldValueINotifyCollectionChanged.CollectionChanged -= newValueINotifyCollectionChanged_CollectionChanged;

            var newValueINotifyCollectionChanged = newValue as INotifyCollectionChanged;

            if (null != newValueINotifyCollectionChanged)
                newValueINotifyCollectionChanged.CollectionChanged += newValueINotifyCollectionChanged_CollectionChanged;
        public IEnumerable ItemsSource
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }

Xamarin.Forms Responsive Layout from Device Rotation


This is a brain dump on implementing a responsive layout based on a device being in Portrait or Landscape mode.

In summary, I used a ContentView’s ControlTemplate to host a layout that depends on a device being in Portrait or Landscape mode. In addition, I then overrode the OnSizeAllocated method on the ContentPage.


<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

            <ControlTemplate x:Key="PortraitTemplate">
                    <StackLayout VerticalOptions="CenterAndExpand">
                        <Entry Style="{StaticResource RegistrationEntry}" Text="{Binding Email}"    Placeholder="email"  />
                        <Entry Style="{StaticResource RegistrationEntry}" Text="{Binding Password}" Placeholder="password" IsPassword="True" Margin="0,15,0,0"  />

                    <Button Style="{StaticResource RegistrationButton}" Text="Next" FontAttributes="Bold" FontSize="Small" VerticalOptions="Fill" />

            <ControlTemplate x:Key="LandscapeTemplate">
                <Label Text="Landscape" />

    <ContentView ControlTemplate="{StaticResource PortraitTemplate}" />


Code Behind

Override OnSizeAllocated method of a ContentPage and compare page width to height:

    public partial class RegistrationPage1 : ContentPage
		public RegistrationPage1() => InitializeComponent();

        protected override void OnSizeAllocated(double width, double height)
            base.OnSizeAllocated(width, height);

            ControlTemplate = GetTemplate(width, height);

        ControlTemplate GetTemplate(double width, double height) =>
            (height > width) ? TemplateFrom("PortraitTemplate") : TemplateFrom("LandscapeTemplate");

        ControlTemplate TemplateFrom(string templateName) =>
            Resources[templateName] as ControlTemplate;


Brain dump completed.

F#: ViewModel (Dependency Injection)



In this post, I attempt to demonstrate how cool I am at writing proven code for a user’s registration form. Please note that I use the term proven and testable interchangeably.


The viewmodel is the root of the testable codebase for business logic.
As a result, I injected the function (aka: implementation) that handles the submit request for a registration form inside my viewmodel.

Here’s code that shows a workflow accepting the implementation of a submit request inside my viewmodel:

type ViewModel(implementation:Try.SubmitFn) as x =
    let submit() =
        let publishEvents events =
            events |> List.iter(fun event -> eventOccurred.Trigger(event))

        validatedForm |> function
                         | Some form ->
                                form |> Command.Execute
                                     |> In.SubmitRegistration.workflow implementation
                                     |> publishEvents
                         | None -> ()

Here’s the entire viewmodel:

namespace Nikeza.Mobile.UILogic.Registration

open System.Windows.Input
open Nikeza.Mobile.UILogic
open Nikeza.Mobile.Profile.Commands.Registration
open Nikeza.Mobile.Profile.Events
open Adapter
open In

type Form = Registration.Types.Form

module Updates =
    let statusOf formValidated events = 
        events |> List.exists formValidated

type ViewModel(implementation:Try.SubmitFn) as x =

    let mutable validatedForm = None

    let eventOccurred = new Event<_>()

    let validate() =
        let isValidated = function
            | FormValidated form -> validatedForm <- Some form; true
            | _ -> false

        { Form.Email=    x.Email
          Form.Password= x.Password
          Form.Confirm=  x.Confirm
          |> ofUnvalidated
          |> Validate.Execute 
          |> In.ValidateRegistration.workflow
          |> Updates.statusOf isValidated
    let submit() =
        let publishEvents events =
            events |> List.iter(fun event -> eventOccurred.Trigger(event))

        validatedForm |> function 
                         | Some form -> 
                                form |> Command.Execute 
                                     |> In.SubmitRegistration.workflow implementation
                                     |> publishEvents
                         | None -> ()

    let validateCommand = DelegateCommand( (fun _ -> x.IsValidated <- validate()) , fun _ -> true)

    let submitCommand =   DelegateCommand( (fun _ -> submit() |> ignore), 
                                            fun _ -> x.IsValidated <- validate(); x.IsValidated )

    let mutable email =    ""
    let mutable password = ""
    let mutable confirm =  ""
    let mutable isValidated = false

    member x.Validate = validateCommand :> ICommand
    member x.Submit =   submitCommand   :> ICommand

    member x.EventOccured = eventOccurred.Publish

    member x.Email
             with get() =      email 
             and  set(value) = email <- value

    member x.Password
             with get() =      password
             and  set(value) = password <- value

    member x.Confirm
        with get() =      confirm
        and  set(value) = confirm <- value

    member x.IsValidated
             with get() =      isValidated
             and  set(value) = isValidated <- value


An automated test targeting business logic should provide its own implementation for submitting a registration request.

My test for submitting a registration form is as follows:

let ``Registration submitted after being validated`` () =
    // Setup
    let mutable registrationSucceeded = false

    let registration = ViewModel(mockSubmit)

                .Add(fun event -> 
                         event |> function
                                  | RegistrationSucceeded _ -> registrationSucceeded <- true
                                  | RegistrationFailed    _ -> registrationSucceeded <- false)


    // Test

    // Verify
    registrationSucceeded |> should equal true

Test API

As I stated earlier, I try to be cool when I write code. Thus, to validate my coolness, I used a type extension to initialize the registration viewmodel.

Here’s my test API:

module TestAPI

open Nikeza.Mobile.UILogic.Registration
open Try

let someEmail =    "scott@abc.com"
let somePassword = "some_password"

let mockSubmit : SubmitFn =
    fun _ -> Ok { Id =        ""
                  FirstName = ""
                  LastName =  ""
                  Email =     ""
                  Bio =       ""
                  ImageUrl =  ""
                  Sources =   []

type ViewModel with

    member x.FillIn () =
           x.Email    <- someEmail
           x.Password <- somePassword
           x.Confirm  <- somePassword


The workflow below relies on a SubmitFn which was originally injected into my viewmodel.

The workflow that receives the implementation of this dependency is as follows:

module SubmitRegistration =
    type private SubmitWorkflow = SubmitFn -> Command -> RegistrationSubmissionEvent list

    let workflow : SubmitWorkflow =
        fun submitFn command -> command |> function
            Command.Execute form ->
                            form |> submitFn
                                 |> ResultOf.Submit.Executed
                                 |> Are.Registration.Submission.events

Building a Trading App (Xamarin.Forms & F#)


This is my fourth post on my journey of building a trading app using F# and Xamarin.Forms. In my last post, I brain-dumped XAML and F# for selling shares of stock. In this post, I will brain-dump the syntax for buying shares of stock for both the UI and viewmodels.

Solution Explorer

I modeled my solution explorer to reflect my interpretation of Clean Architecture:


The user-experience for buying shares is the following:


Here’s the XAML for the Buy page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"              xmlns:manageTrades="clr-namespace:ManageTrades.ViewModels;assembly=ManageTrades"              x:Class="FnTrade.BuyPage">

    <Grid Margin="10,5">
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />

            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />

        <Label Grid.Row="0" Grid.Column="0" Text="{Binding Symbol,     StringFormat='Buying ({0:F0})'}}" FontSize="Large" />
        <Label Grid.Row="2" Grid.Column="0" Text="{Binding StockPrice, StringFormat='{}{0:c} per share'}}"        FontSize="Medium" HorizontalTextAlignment="Start" HorizontalOptions="Start" />
        <Label Grid.Row="3" Grid.Column="0" Text="{Binding Total,      StringFormat='{}{0:c} Invested'}}" FontSize="Medium" HorizontalTextAlignment="Start" HorizontalOptions="Start" />
        <Label Grid.Row="4" Grid.Column="1" Text="{Binding Balance,    StringFormat='{}{0:c} balance'}}" FontSize="Large" HorizontalOptions="Start" />

        <Entry Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding BuyQty, Mode=TwoWay}"                 Placeholder="Enter number of shares to buy" HorizontalTextAlignment="Center" Keyboard="Numeric" />

        <Label Grid.Row="7" Grid.Column="1" Text="{Binding BuyValue, StringFormat='{}{0:c}'}" HorizontalTextAlignment="End" />

        <Button Grid.Row="9" Grid.Column="0" Grid.ColumnSpan="2" Text="Confirm"                  Command="{Binding Confirm}" IsEnabled="{Binding CanBuy}" />


The code-behind of the Buy page subscribes to a confirmation-request event:

using ManageTrades.ViewModels;
using Xamarin.Forms;

namespace FnTrade
    using static Core.Entities;
    using static Integration.Factories;

    public partial class BuyPage : ContentPage
        public BuyPage(BuyViewModel viewModel)
            BindingContext = viewModel;

            getDispatcher().ConfirmBuyRequested += async (s, e) =>
                    var requestInfo = e as RequestInfo;
                    var confirmed = await DisplayAlert("Confirmation",
                                          $"Buying ({(requestInfo).Quantity }) shares of {requestInfo.Symbol}?",
                                          "Confirm", "Cancel");
                    if (confirmed) getDispatcher().ExecuteBuy(requestInfo);

When the purchase of shares is confirmed, the app presents a purchase request confirmation.

The following is the XAML for the purchase shares request confirmation:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"              x:Class="FnTrade.RequestBuyConfirmedPage">

    <Grid Margin="10,5">
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />

            <ColumnDefinition />
            <ColumnDefinition />

        <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Text="Request Sent"                 FontSize="Large" TextColor="Green" FontAttributes="Bold" HorizontalOptions="Center" />

        <StackLayout Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalOptions="Center">
            <StackLayout  Orientation="Horizontal" VerticalOptions="Center">
                <Label Text="{Binding Quantity, StringFormat='Buy ({0:F0}) shares of'}}"                         FontSize="Medium" HorizontalOptions="Center" HorizontalTextAlignment="Center" />

                <Label Text="{Binding Symbol}"                        FontSize="Medium" HorizontalOptions="Start" />

            <Label Grid.Row="2" Grid.Column="1" Text="{Binding Total, StringFormat='{}{0:c}'}}"                    FontSize="24" FontAttributes="Bold" HorizontalOptions="End" />


Here’s the viewmodel for buying shares:

namespace ManageTrades.ViewModels

open System
open System.Windows.Input
open Core.IntegrationLogic
open Core.Entities
open Integration.Factories
open Services

type BuyViewModel(info:SharesInfo) as this =

    inherit ViewModelBase()

    let dispatcher = getDispatcher()
    let accountId =  getAccountId()
    let broker =     getBroker() :> IBroker

    let mutable buyQty = ""
    let mutable canBuy = false
    let mutable buyValue = 0m

    let confirm = DelegateCommand( (fun _ -> this.ConfirmBuy()) ,
                                    fun _ -> true ) :> ICommand

    member this.Symbol     with get() = info.Shares.Symbol
    member this.Balance    with get() = info.Balance
    member this.StockPrice with get() = info.PricePerShare
    member this.Total      with get() = ((decimal)info.Shares.Qty * info.PricePerShare)

    member this.BuyQty
        with get() =      buyQty
        and  set(value) = buyQty <- value
                          let success , validQty = Int32.TryParse buyQty
                          if  success then this.CanBuy <- info.PricePerShare
                                                          *(decimal)validQty  <= this.Balance
                          else this.CanBuy <- false
                          base.NotifyPropertyChanged(<@ this.BuyQty @>)
    member this.BuyValue
        with get() =      buyValue
        and  set(value) = buyValue <- value
                          base.NotifyPropertyChanged(<@ this.BuyValue @>)

    member this.CanBuy   with get() =      canBuy
                         and  set(value) = canBuy <- value
                                           base.NotifyPropertyChanged(<@ this.CanBuy @>)
    member this.Confirm = confirm

    member private this.ConfirmBuy() =
        if this.CanBuy then
            dispatcher.ConfirmBuy { AccountId = accountId
                                    Symbol    = this.Symbol
                                    Quantity  = Int32.Parse this.BuyQty }

    member private this.UpdateBuyValue() =
        let success , validQty = Int32.TryParse buyQty
        if  success
        then this.BuyValue <- (decimal)validQty * info.PricePerShare
        else this.BuyValue <- 0m

Here’s the viewmodel for the purchase request confirmation:

namespace ManageTrades.ViewModels

open Core.IntegrationLogic
open Core.Entities
open Services
open Integration.Factories

type RequestBuyConfirmedViewModel(request:RequestInfo) =

    inherit ViewModelBase()

    let broker = getBroker() :> IBroker
    let mutable total = 0m

    member this.Symbol   with get() = request.Symbol
    member this.Quantity with get() = request.Quantity
    member this.Total    with get() =      total
                         and  set(value) = total <- value
                                           base.NotifyPropertyChanged(<@ this.Total @>)
    member this.Load() =
        match broker.GetInfo request.Symbol with
        | Some info -> this.Total <- info.Price * (decimal) request.Quantity         | None      -> failwith (sprintf "Failed to retrieve stock information for %s" this.Symbol)

Domain Types

The following module reflects the entities that will be used in my trading app:

module Core.Entities

type StockInfo = {
    Symbol  : string
    Price   : decimal
    DayLow  : decimal
    DayHigh : decimal

type Shares = {
    AccountId : string
    Symbol    : string
    Qty       : int

type SharesInfo ={
    Shares        : Shares
    PricePerShare : decimal
    Total         : decimal
    Balance       : decimal

type Owner = { AccountId:string ; Symbol:string }

type RequestInfo = {
    AccountId : string
    Symbol    : string
    Quantity  : int

type InsufficientFunds = {
    PurchaseAttempt : RequestInfo
    Balance         : decimal
    StockPrice      : decimal

type PurchaseResult =
    | PurchaseRequested of RequestInfo
    | UnknownSymbol     of RequestInfo
    | InvalidQuantity   of RequestInfo
    | InsufficientFunds of InsufficientFunds

type SellResult =
    | SellRequested        of RequestInfo
    | InsufficientQuantity of RequestInfo


The source code for this app can be found here on GitHub.