Embedding QR Code Scanner in Xamarin.Forms

Introduction

In this article, we will learn how to embed and use the barcode scanner inside the screen/page using the Xamarin.Forms Framework. For achieving this, we are going to use “ZXing.Net.Mobile” plugin.

Dropdown in Xamarin.Forms

ZXing.Net.Mobile plugin is a useful plugin to facilitate scanning barcodes as effortless and painless as possible in our own applications works Xamarin.iOS, Xamarin.Android, Tizen, and UWP.

Library Link: https://github.com/Redth/ZXing.Net.Mobile

Without much introduction, we will skip into the coding part of this article.

Coding Part

Steps

Step 1: Creating new Xamarin.Forms Projects.

Step 2: Setting up the scanner in Xamarin.Forms .Net Standard Project

Step 3: Implementation of QR Code Scanner inside the screen/page

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New à Project à Select Xamarin Cross Platform App and Click OK.

Note: Xamarin.Forms version should be greater than 4.5.

Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Setting up the scanner in Xamarin.Forms .Net Standard Project

In this step, we will see how to setup the plugin.

  • Open the Nuget Manager in the Visual Studio Solution by right click the solution and select “Manage Nuget Packages”.
  • Then “ZXing.Net.Mobile” and check all the projects in the solution, install the plugin
  • After the installation, we need to do some additional setup in the platform wise projects.
  • In Android, update the below code blocks in the MainActivity to initialize the plugin.
// In OnCreate method
Xamarin.Essentials.Platform.Init(Application);
ZXing.Net.Mobile.Forms.Android.Platform.Init();

// In Activity to handle the camera permission from the plugin it self.

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Step 3: Implementation of QR Code Scanner inside the screen/page

In this step, we will see how to use the view in Xamarin.Forms.

  • Open your designer file and in my case MainPage.xaml and add the ZxingSannerView as shown below.
    <zxing:ZXingScannerView x:Name="zxing"
                            VerticalOptions="FillAndExpand"/>
  • Add Label below the ZxingSannerView to see the results when the bar/QR code scanned.
  • Then add the below event to know the successful scan from the control.
    zxing.OnScanResult += (result) =>
          Device.BeginInvokeOnMainThread(() =>
          {
                lblResult.Text = result.Text;
          });

Full Code implementation of ZXing Scanner View in MainPage

Here, we will see the full code for Main Page.

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        zxing.OnScanResult += (result) =>
            Device.BeginInvokeOnMainThread(() =>
            {
                lblResult.Text = result.Text;
            });
    }


    protected override void OnAppearing()
    {
        base.OnAppearing();
        zxing.IsScanning = true;
    }

    protected override void OnDisappearing()
    {
        zxing.IsScanning = false;
        base.OnDisappearing();
    }
}

Demo

The following screens shows the output this tutorial and it is awesome to have this dropdown in Xamarin.Forms

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Dropdown control in Xamarin.Forms – Part Two

banner_dropdown_part2

Introduction

In this article, we will learn how to create Dropdown in Xamarin.Forms (Xamarin.iOS). As we learned in the previous article about by default, Android Platform has dropdown called as “Spinner”, but iOS Platform has no dropdown like Android Spinner and how to achieve the dropdown in Xamarin.Forms for Android Platform using Custom renderer approach. In this article, we are going to create a custom renderer to achieve the dropdown for iOS platform in Xamarin.Forms.

Dropdown in Xamarin.Forms

Please refer the previous article to know, how to achieve the dropdown in Android Platform. I have done changes commonly for Android and iOS in this article.

We will go for custom renderer approach to have a new control to wrap a Platform specific control. I am going to use “FPTInformationSystem Dropdown” and refer the below link to know more details for this control.

Library Link: https://github.com/FPTInformationSystem/Dropdown-Xamarin-iOS

Without much introduction, we will skip into the coding part of this article.

Coding Part

Steps

Here, I will explain the steps to create Dropdown in Xamarin.Forms.

Step 1: Creating new Xamarin.Forms Projects.

Step 2: Creating a Dropdown view in Xamarin.Forms .NetStandard Project

Step 3: Wrapping FPT dropdown for Dropdown control in iOS Project.

Step 4: Implementation of Dropdown & It’s Demo for iOS Platform.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New à Project à Select Xamarin Cross Platform App and Click OK.

Note: Xamarin.Forms version should be greater than 4.5.

Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating a Dropdown view in Xamarin.Forms .NetStandard Project

In this step, we will see how to create a dropdown view with required properties.

  • Create a class named as “Dropdown” and inherit the Dropdown with “Label”. That is Dropdown is child of View.
    public class Dropdown :  Label
    {
      //...
    }
  • Then we will create a required bindable properties. First we will see, what are all the properties & events required for dropdown.
    1. ItemsSource – To assign the list of data to be populated in the dropdown.
    2. SelectedIndex – To identify the index of selected values from the ItemsSource.
    3. ItemSelected – Event for performing action when the item selected in the dropdown.
  • Create a bindable property for the ItemsSource as shown in below.
    public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(
          propertyName: nameof(ItemsSource),
          returnType: typeof(List<string>),
          declaringType: typeof(List<string>),
          defaultValue: null);
    
    public List<string> ItemsSource
    {
          get { return (List<string>)GetValue(ItemsSourceProperty); }
          set { SetValue(ItemsSourceProperty, value); }
    }

Step 3: Wrapping FPT dropdown for Dropdown control in iOS Project.

In this step, we will see “How to wrap the iOS Spinner Control for Dropdown View”.

  • We need to download the DLL of FPT dropdown from the below GitHub link and include as a reference for the iOS project. Library Download Link
  • Create a class file named as “DropdownRenderer” in your iOS client project and add View Renderer as shown in below. I am using Label renderer for displaying the dropdown when the control tapped.
    public class DropdownRenderer :  LabelRenderer
    {
          XFDropdown xfDropdown = null;
          XIDropdown dropDown = null;
          public DropdownRenderer()
          {
    
          }    
          // ...
    }
  • Then Override the methods “OnElementChanged” and “OnElementPropertyChanged”. OnElementChanged method is triggered on element/control initiation. OnElementPropertyChanged method is called when the element property changes.
  • Set Control properties to LabelRenderer in OnElementChanged override method as shown in below.
  • We need to follow the below for initiating the FPT dropdown and open when the label tapped.
    if (Control != null)
    {
        dropDown = new XIDropdown();
        xfDropdown = (XFDropdown)e.NewElement;
        dropDown.AnchorView = new WeakReference<UIView>(Control);
        nfloat y = dropDown.Bounds.Height;
        if (y == 0)
            y += 40;
        dropDown.TopOffset = new CoreGraphics.CGPoint(0, -y);
        dropDown.BottomOffset = new CoreGraphics.CGPoint(0, y);
    
        //...
    
        UITapGestureRecognizer labelTap = new UITapGestureRecognizer(() =>
        {
            dropDown.Show();
        });
    
        if (xfDropdown.SelectedIndex > -1)
            Control.Text = xfDropdown.ItemsSource[xfDropdown.SelectedIndex];
        Control.UserInteractionEnabled = true;
        Control.AddGestureRecognizer(labelTap);
    }
  • Set Items Source from Xamarin.Forms Dropdown to FPT dropdown control as shown in below.
    string[] data = xfDropdown.ItemsSource.ToArray();
    dropDown.DataSource = data;
  • Set default selection of item from selected index as shown in below.
    if(xfDropdown.SelectedIndex != -1)
    {
          dropDown.SelectRow(xfDropdown.SelectedIndex);
    }
  • Create an item selected event for FPT dropdown and invoke the dropdown event created as shown below
    // ...
    
    dropDown.SelectionAction = (nint idx, string item) =>
    {
          if (xfDropdown.SelectedIndex == idx)
          {
                dropDown.Dispose();
                return;
          }
    
          xfDropdown.SelectedIndex = Convert.ToInt32(idx);
          Control.Text = item;
          xfDropdown.OnItemSelected(xfDropdown.SelectedIndex);
    };
  • In the same way, we will assign ItemsSource & SelectedIndex to FPT dropdown when the property changes using OnElementPropertyChanged as shown below.
    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
          base.OnElementPropertyChanged(sender, e);
          dropDown.Width = (nfloat)Element.Width;
          if (e.PropertyName == XFDropdown.SelectedIndexProperty.PropertyName)
          {
                if (xfDropdown.SelectedIndex > -1)
                      Control.Text = xfDropdown.ItemsSource[xfDropdown.SelectedIndex];
                dropDown.SelectRow(xfDropdown.SelectedIndex);
          }
    
          if (e.PropertyName == XFDropdown.ItemsSourceProperty.PropertyName)
          {
                string[] data = xfDropdown.ItemsSource.ToArray();
                dropDown.DataSource = data;
          }
    }
  • Add Export Renderer above the namespace to link dropdown view in .NetStandard project to iOS Client Project. This is very important step for any custom renderer approach.
    [assembly: ExportRenderer(typeof(Dropdown), typeof(DropdownRenderer))]
    namespace XF.Ctrls.iOS

Full Code of Dropdown Renderer

Here, we will see the full code for Dropdown Renderer.

[assembly: ExportRenderer(typeof(XFDropdown), typeof(DropdownRenderer))]
namespace XF.Ctrls.iOS
{
    public class DropdownRenderer : LabelRenderer
    {

        XFDropdown xfDropdown = null;
        XIDropdown dropDown = null;

        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                dropDown = new XIDropdown();
                xfDropdown = (XFDropdown)e.NewElement;
                dropDown.AnchorView = new WeakReference<UIView>(Control);
                nfloat y = dropDown.Bounds.Height;
                if (y == 0)
                    y += 40;

                dropDown.TopOffset = new CoreGraphics.CGPoint(0, -y);
                dropDown.BottomOffset = new CoreGraphics.CGPoint(0, y);
                string[] data = xfDropdown.ItemsSource.ToArray();
                dropDown.DataSource = data;
                Control.Text = data[0];
                dropDown.SelectionAction = (nint idx, string item) =>
                {
                    if (xfDropdown.SelectedIndex == idx)
                    {
                        dropDown.Dispose();
                        return;
                    }
                    xfDropdown.SelectedIndex = Convert.ToInt32(idx);
                    Control.Text = item;
                    xfDropdown.OnItemSelected(xfDropdown.SelectedIndex);
                };

                UITapGestureRecognizer labelTap = new UITapGestureRecognizer(() =>
                {
                    dropDown.Show();
                });

                if (xfDropdown.SelectedIndex > -1)
                    Control.Text = xfDropdown.ItemsSource[xfDropdown.SelectedIndex];
                Control.UserInteractionEnabled = true;
                Control.AddGestureRecognizer(labelTap);
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            dropDown.Width = (nfloat)Element.Width;
            if (e.PropertyName == XFDropdown.SelectedIndexProperty.PropertyName)
            {
                if (xfDropdown.SelectedIndex > -1)
                    Control.Text = xfDropdown.ItemsSource[xfDropdown.SelectedIndex];
                dropDown.SelectRow(xfDropdown.SelectedIndex);
            }
            if (e.PropertyName == XFDropdown.ItemsSourceProperty.PropertyName)
            {
                string[] data = xfDropdown.ItemsSource.ToArray();
                dropDown.DataSource = data;
            }
        }
    }
}

Step 4: Implementation of Dropdown & It’s Demo for iOS Platform

In this step, we will see how to use the view in Xamarin.Forms.

  • Open your designer file and in my case MainPage.xaml and add the control as shown below.
    <local:Dropdown HorizontalOptions="FillAndExpand"
                    VerticalOptions="Center"
                    BackgroundColor="LawnGreen"
                    x:Name="dropdown"/>
  • Set ItemsSource and SelectedIndex as shown in below.
    dropdown.ItemsSource = Items1;
    dropdown.SelectedIndex = 1;
  • Add item selection event to dropdown as shown in below.
    public MainPage()
    {
          //...
          dropdown.ItemSelected += OnDropdownSelected;
    }
    
    private void OnDropdownSelected(object sender, ItemSelectedEventArgs e)
    {
          label.Text = Items1[e.SelectedIndex];
    }

Full Code implementation of Dropdown in MainPage

Here, we will see the full code for Main Page.

namespace XF.Ctrls
{
    public partial class MainPage : ContentPage
    {
        List<string> Items1 = new List<string>();
        List<string> Items2 = new List<string>();
        bool IsItem1 = true;

        public MainPage()
        {
            InitializeComponent();

            for (int i = 0; i < 4; i++)
            {
                Items1.Add(i.ToString());
            }

            for (int i = 0; i < 10; i++)
            {
                Items2.Add(i.ToString());
            }

            dropdown.ItemsSource = Items1;
            dropdown.SelectedIndex = 1;
            dropdown.ItemSelected += OnDropdownSelected;
        }

        private void OnDropdownSelected(object sender, ItemSelectedEventArgs e)
        {
            label.Text = IsItem1 ? Items1[e.SelectedIndex] : Items2[e.SelectedIndex];
        }

        private void btn_Clicked(object sender, EventArgs e)
        {
            dropdown.ItemsSource = IsItem1 ? Items2 : Items1;
            dropdown.SelectedIndex = IsItem1 ? 5 : 1;
            IsItem1 = !IsItem1;
        }
    }
}

Demo

The following screens shows the output this tutorial and it is awesome to have this dropdown in Xamarin.Forms.

Platform

Screenshots

Android

iOS

This article covers the implementation of new dropdown control in iOS Platform. Refer my previous article for the implementation of Dropdown in Android Platform.

My plan is to create a dropdown control for supporting all platforms and offering this control as a standard plugin.

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Multiple Item Selection Picker in Xamarin.Forms

Introduction

In this article, we will learn how to create Multi-Item Selection Picker Control in Xamarin.Forms. To achieve this, I have created a common control will open the selection on clicking the control like the picker control. Without making any further delay, we will see the steps one by one to implement the multi-item selection control.

Multi Item Selection Picker

Basically, I am creating a new custom control inherited with Entry control, which will focus the picker when the focused. The Multi-Item Selection Picker listing is nothing but a content page with list view control has the check box template. Also, I have used await able content page which will return the data when the page closes.

Without much introduction, we will skip into the coding part of this article.

Coding Part

Steps

Here, I will explain the steps to create Multi Item Selection Picker in Xamarin.Forms.

Step 1: Creating new Xamarin.Forms Projects.

Step 2: Creating a custom control view in Xamarin.Forms .NetStandard Project

Step 3: Creating the Custom Checkbox listing page.

Step 4: Implementation of Multi Item Selection Picker & It’s Demo.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New à Project à Select Xamarin Cross Platform App and Click OK.

Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.


Step 2: Creating a custom control view in Xamarin.Forms .NetStandard Project

  1. Create a class named as “MultiSelectionPicker” and inherit with “Entry” to have the basic properties like Placeholder, Focused & Unfocused event.
  2. Then we will create a required bindable properties. First we will see, what are all the properties & events required for dropdown.
    public class  MultiSelectionPicker : Entry
    {
    
          //...
    
    }
    1. ItemsSource – To assign the list of data to be populated in the picker.
    2. SelectedIndices – To identify the index of selected values from the ItemsSource.
    3. Title – To set the title for the control page
  3. Create a bindable property for the ItemsSource as shown in below.
    public static readonly BindableProperty ItemsSourceProperty =           BindableProperty.Create("ItemsSource", typeof(List<string>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay);
    public List<string> ItemsSource
    {
        get { return (List<string>)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }
  4. Create a bindable property for the SelectedIndices as shown in below.
    public static readonly BindableProperty SelectedIndicesProperty = BindableProperty.Create("SelectedItems", typeof(List<int>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay,
        propertyChanged: SelectedIndexChanged);
    
    public List<int> SelectedIndices
    {
        get { return (List<int>)GetValue(SelectedIndicesProperty); }
        set { SetValue(SelectedIndicesProperty, value); }
    }
  5. Create a bindable property for the Title as shown in below.
    public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(MultiSelectionPicker), null);
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    } 

Step 3: Creating the Custom Checkbox listing page.

In this step, we will see How to design the picker and awaitable page to return result when the screen closed by the user.

  1. Create await able content page by using the following code block which is base page for the checkbox listing page.
    public class BasePage<T> : ContentPage
    {
        public event Action<T> PageDisappearing;
        protected T _navigationResut;
    
        public BasePage()
        {
    
        }
    
        protected override void OnDisappearing()
        {
            PageDisappearing?.Invoke(_navigationResut);
            if (PageDisappearing != null)
            {
                foreach (var @delegate in PageDisappearing.GetInvocationList())
                {
                    PageDisappearing -= @delegate as Action<T>;
                }
            }
            base.OnDisappearing();
        }
    }
    
    Here, T is nothing but the template which will be any data type like string, bool and so.
  2. Create a xaml file named as CheckboxPage.xaml. Set step 1 created page as a base page.
  3. Then paste the following code xaml and xaml.cs file where the data type is string. Refer the below codes for the screen design and property assignments.
<?xml version="1.0" encoding="utf-8" ?>
<pages:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
                xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                xmlns:pages="clr-namespace:Xamarin.Forms"
                x:Class="Xamarin.Forms.CheckboxPage"
                x:TypeArguments="x:String">
    <ContentPage.Content>
        <StackLayout Padding="5">
            <ListView x:Name="listView"
                      ItemTapped="listView_ItemTapped"
                      SeparatorVisibility="None"
                      VerticalScrollBarVisibility="Never"
                      HorizontalScrollBarVisibility="Never">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                                <Label Text="{Binding Text}" VerticalOptions="Center" HorizontalOptions="StartAndExpand"/>
                                <CheckBox IsChecked="{Binding IsChecked}" HorizontalOptions="EndAndExpand" Color="Black"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <StackLayout HorizontalOptions="End"
                         Orientation="Horizontal">
                <Button Text="Cancel" Clicked="Cancel_Clicked" HorizontalOptions="Center" VerticalOptions="End" BackgroundColor="Transparent"/>
                <Button Text="Done" Clicked="Done_Clicked" HorizontalOptions="Center" VerticalOptions="End" BackgroundColor="Transparent"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</pages:BasePage>
  1. The above code contains the cancel and done button for cancelling and updating the picker selection.
public partial class CheckboxPage : BasePage<string>
{
    private List<CheckedItem> ItemsSource;
    public CheckboxPage(List<string> itemsSource, List<int> selectedIndices)
    {
        InitializeComponent();
        List<CheckedItem> list = new List<CheckedItem>();
        for (int i = 0; i < itemsSource.Count; i++)
        {
            list.Add(new CheckedItem()
            {
                Text = itemsSource[i],
                IsChecked = false,
                Position = i
            });
        }
        ItemsSource = list;
        foreach (int i in selectedIndices)
        {
            list[i].IsChecked = true;
        }
        listView.ItemsSource = list;
    }

    private void listView_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        ((ListView)sender).SelectedItem = null;
    }

    private void Done_Clicked(object sender, EventArgs e)
    {
        List<CheckedItem> list = (List<CheckedItem>)listView.ItemsSource;
        _navigationResut = string.Join(",", list.Where(x => x.IsChecked).Select(x => x.Position).ToArray());
        Navigation.PopModalAsync();
    }

    private void Cancel_Clicked(object sender, EventArgs e)
    {
        //List<CheckedItem> list = ItemsSource;
        _navigationResut = "";// string.Join(",", list.Where(x => x.IsChecked).Select(x => x.Position).ToArray());
        Navigation.PopModalAsync();
    }
}

public class CheckedItem
{
    public int Position { get; set; }
    public bool IsChecked { get; set; }
    public string Text { get; set; }
}
  1. After that, go to the custom control “Multiselectionpicker.cs” and create the following function which will open the page a modal page with TaskCompletionSource.
public async Task<T> NavigateToModal<T>(BasePage<T> page)
{
    var source = new TaskCompletionSource<T>();
    page.PageDisappearing += (result) =>
    {
        var res = (T)Convert.ChangeType(result, typeof(T));
        source.SetResult(res);
    };
    await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
    return await source.Task;
}
  1. Create focused event in the multiselectpicker and call the above mentioned function
Focused += async (e, s) =>
{
    if (s.IsFocused)
    {
        Unfocus();
        string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
        if (item == "")
            return;
    }
};
  1. In the focused event, get the selection indexes and assign to the entry with comma separator.
Focused += async (e, s) =>
{
    if (!IsControlLoaded && Device.RuntimePlatform == Device.UWP)
    {
        IsControlLoaded = true;
        Unfocus();
        return;
    }
    if (s.IsFocused)
    {
        Unfocus();
        string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
        if (item == "")
            return;
        SelectedIndices = item.Split(',').Select(x => Convert.ToInt32(x)).ToList();
        List<string> selectedItems = new List<string>();
        foreach (int i in SelectedIndices)
        {
            selectedItems.Add(ItemsSource[i]);
        }
        Text = string.Join(", ", selectedItems);
    }
};

Full Code of MultiSelectPicker.cs

namespace Xamarin.Forms
{
    public class MultiSelectionPicker : Entry
    {
        public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(MultiSelectionPicker), null);
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
        public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", typeof(List<string>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay);
        public List<string> ItemsSource
        {
            get { return (List<string>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
        public static readonly BindableProperty SelectedIndicesProperty = BindableProperty.Create("SelectedItems", typeof(List<int>), typeof(MultiSelectionPicker), null, BindingMode.TwoWay,
            propertyChanged: SelectedIndexChanged);

        public List<int> SelectedIndices
        {
            get { return (List<int>)GetValue(SelectedIndicesProperty); }
            set { SetValue(SelectedIndicesProperty, value); }
        }

        private static void SelectedIndexChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var ctrl = (MultiSelectionPicker)bindable;
            if (ctrl == null)
                return;
            List<string> selectedItems = new List<string>();
            foreach (int i in ctrl.SelectedIndices)
            {
                selectedItems.Add(ctrl.ItemsSource[i]);
            }
            ctrl.Text = string.Join(", ", selectedItems);
        }

        bool IsControlLoaded = false;

        public MultiSelectionPicker()
        {
            Focused += async (e, s) =>
            {
                if (!IsControlLoaded && Device.RuntimePlatform == Device.UWP)
                {
                    IsControlLoaded = true;
                    Unfocus();
                    return;
                }
                if (s.IsFocused)
                {
                    Unfocus();
                    string item = await NavigateToModal<string>(new CheckboxPage(ItemsSource, SelectedIndices));
                    if (item == "")
                        return;
                    SelectedIndices = item.Split(',').Select(x => Convert.ToInt32(x)).ToList();
                    List<string> selectedItems = new List<string>();
                    foreach (int i in SelectedIndices)
                    {
                        selectedItems.Add(ItemsSource[i]);
                    }
                    Text = string.Join(", ", selectedItems);
                }
            };
        }

        public async Task<T> NavigateToModal<T>(BasePage<T> page)
        {
            var source = new TaskCompletionSource<T>();
            page.PageDisappearing += (result) =>
            {
                var res = (T)Convert.ChangeType(result, typeof(T));
                source.SetResult(res);
            };
            await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
            return await source.Task;
        }
    }

    public class BasePage<T> : ContentPage
    {
        public event Action<T> PageDisappearing;
        protected T _navigationResut;

        public BasePage()
        {

        }

        protected override void OnDisappearing()
        {
            PageDisappearing?.Invoke(_navigationResut);
            if (PageDisappearing != null)
            {
                foreach (var @delegate in PageDisappearing.GetInvocationList())
                {
                    PageDisappearing -= @delegate as Action<T>;
                }
            }
            base.OnDisappearing();
        }
    }
}

Step 4: Implementation of Multi Item Selection Picker & It’s Demo.

In this step, we will see how to use the view in Xamarin.Forms.

  1. Open your designer file and in my case MainPage.xaml and add the control as shown below.
<control:MultiSelectionPicker x:Name="picker" BackgroundColor="White"/>
  1. Set ItemsSource and SelectedIndices as shown in below.
picker.ItemsSource = new List<string>() { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6" };
picker.SelectedIndices = new List<int>() { 2,4,5 };

Demo



Download Code

You can download the full source code from GitHub. If you like this article, do like, share and star the repo in GitHub.


Gradient View in Xamarin.Forms using Magic Gradients



Introduction:

In this tutorial, we will learn how to implement Gradient view in Xamarin.Forms with very simple steps. To achieve the gradient view, we are using Magic Gradients plugin for Xamarin Forms. Magic Gradients is a NuGet that provide a possibility to add beautiful and enhanced gradients into Xamarin.Forms applications. It supports all common Xamarin platforms, such as Android, iOS and UWP. It is built upon SkiaSharp to draw a simple multi-color or multi-layer engaged gradients. Without further delay, we will skip into the coding part of the article.

Magic Gradient:

Magic Gradients provides GradientView control which is just a surface for SkiaSharp inside. Inside GradientView you need to set GradientSource which is a default container. Inside it you can place single gradients LinearGradient, RadialGradient or multiple gradients with GradientCollection as a top element.

Coding Part:

Steps:

I have split the coding part into 3 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Setting up the libraries.
  3. Implementation of the Gradient Views

Step 1: Creating new Xamarin.Forms Projects

  • Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
  • Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Setting up the libraries

  • We need to install the NuGet package for Magic Gradients by using any of the below methods.
    1. Search for MagicGradients in NuGet browser.
    2. Using Package Manager CLI: “Install-Package MagicGradients”.
    3. Using the .Net CLI: “dotnet add package MagicGradients”.
    4. Editing your csproj file by adding the following and restoring the project.
    <PackageReference Include="MagiGradients" Version="1.0.0" />
  • We should install it only for our "Core" project.

Step 3: Implementation of the Gradient Views

  • Open your designer file and add the following namespace for magic gradient view.
    xmlns:magic="clr-namespace:MagicGradients;assembly=MagicGradients"
  • After that we can using Magic Gradients as like in the following code snippet. Inside it you can place single gradients LinearGradient, RadialGradient or multiple gradients with GradientCollection as a top element.
  • Here, we have taken LinearGradient as an example.
    <magic:GradientView VerticalOptions="FillAndExpand">
        <magic:GradientView.GradientSource>
            <magic:LinearGradient Angle="90">
                <magic:GradientStop Color="Orange" Offset="0" />
                <magic:GradientStop Color="#ff0000" Offset="0.6" />
            </magic:LinearGradient>
        </magic:GradientView.GradientSource>
    </magic:GradientView>
  • We can use gradient collection for more than one gradient sources like below.
    <magic:GradientView VerticalOptions="FillAndExpand">
        <magic:GradientView.GradientSource>
            <magic:GradientCollection>
                <magic:LinearGradient Angle="45">
                    <magic:GradientStop Color="Orange" Offset="0" />
                    <magic:GradientStop Color="#ff0000" Offset="0.6" />
                </magic:LinearGradient>
                <magic:LinearGradient Angle="90">
                    <magic:GradientStop Color="#33ff0000" Offset="0.4" />
                    <magic:GradientStop Color="#ff00ff00" Offset="1" />
                </magic:LinearGradient>
            </magic:GradientCollection>
        </magic:GradientView.GradientSource>
    </magic:GradientView>

Output

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Multilingual Implementation - Xamarin.Forms



Introduction:

In this tutorial, we will learn how to implement Multi-Lingual in Xamarin.Forms without using external plugins or platform wise implementation with dependency service. The latest Xamarin forms offers .net standard to implement the multilingual and without further delay, we will skip into the coding part of the article.

Coding Part:

Steps:

I have split the coding part into 4 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Creating App Resource files for multi-language.
  3. Language Management
  4. Implementation of Multi-Lingual.

Step 1: Creating new Xamarin.Forms Projects

  • Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
  • Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating App Resource files for multi-language

  • Add one resource file as base file with the name your preferred name. In my case, I kept the name of the file as “AppResources.resx” and it will be used as default language file.
  • Then add one resource file for each language you want to support. We must follow a specific naming convention for each file as the base resources file followed by a period (.) and then the language code.
  • For Example
    Language Language Code File Name
    Tamil ta AppResources.ta.resx
    French fr AppResources.fr.resx

  • Then add resources with the same name with language specific values in each resource files as like in the below screenshot.

Step 3: Language Management

In this step, we will see how to handle the multilingual for Xamarin.Forms.

  • Get Device Language
    CultureInfo.InstalledUICulture
  • Get or Set the actual language
    CultureInfo language = new CultureInfo("ta");
    Thread.CurrentThread.CurrentUICulture = language;
    AppResources.Culture = language;

Step 4: Implementation of Multi-Lingual

  • Open your designer file and add the resources as shown in below code snippet.
    <?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:resource="clr-namespace:MultilingualXFSample.Resources"
                 x:Class="MultilingualXFSample.MainPage">
            <Label Text="{x:Static resource:AppResources.WelcomeText}"
                   FontSize="Large"/>
    </ContentPage>
  • By default, the app will take the base resource file. By passing the language code will takes the language specific resource file and we can set the language as shown in below code snippet in runtime
    CultureInfo language = new CultureInfo("ta");
    Thread.CurrentThread.CurrentUICulture = language;
    AppResources.Culture = language;
    Application.Current.MainPage = new NavigationPage(new MainPage());

Output

Default - English Tamil French

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.

Placeholder for Picker - Xamarin.Forms

Introduction

In this tutorial, we will learn how to handle the Placeholder issue in Xamarin.Forms for Picker Control. Xamarin.Forms Picker Control is a combination of EditText plus AlertDialog for Android and UITextField plus UIPicker for iOS. The Title property of Xamarin.Forms Picker Control is a property to set title for AlertDialog plus Hint for EditText for Android and Placeholder for UITextField.

For Example, we are setting the title property of the picker control is “Title” and it has items source and selected index of the control as “-1” then the control will shows “Title” in Placeholder and title of the alert or popup. Sometimes, it is meaning less to use this control due to this.

To avoid this issue, I have created a customer render for Android and iOS to override this default behavior of picker. Without much delay, we will skip into the coding part of the article.

Coding Part:

Steps:

I have split the coding part into 5 steps as in the following.

  1. Creating new Xamarin.Forms Projects.
  2. Creating Custom Picker inherited from picker.
  3. Custom Renderer for Custom Picker in Android.
  4. Custom Renderer for Custom Picker in iOS.
  5. Implementation of the Custom Picker Control.

Step 1: Creating new Xamarin.Forms Projects

Create New Project by Selecting New -> Project -> Select Xamarin Cross Platform App and Click OK.
Then Select Android and iOS Platforms as shown below with Code Sharing Strategy as PCL or .Net Standard and Click OK.

Step 2: Creating Custom Picker inherited from picker

  1. Create a Custom Picker Control class named as “PLPicker” and it is inherited from Xamarin.Forms Picker.
  2. Create a property for Placeholder and is named as Placeholder like below.
    public class PLPicker : Picker
    {
        public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(
            propertyName: nameof(Placeholder),
            returnType: typeof(string),
            declaringType: typeof(string),
            defaultValue: string.Empty);
    
        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }
    
    }

Step 3: Custom Renderer for Custom Picker in Android

In this step, we will create a custom renderer in Android for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Hint = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.Droid
    {
        public class PLPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
        {
            PLPicker picker = null;
            public PLPickerRenderer(Context context) : base(context)
            {
    
            }
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    UpdatePickerPlaceholder();
                    if (picker.SelectedIndex <= -1)
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (picker != null)
                {
                    if (e.PropertyName.Equals(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            protected override void UpdatePlaceHolderText()
            {
                UpdatePickerPlaceholder();
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Hint = picker.Placeholder;
            }
        }
    }

Step 4: Custom Renderer for Custom Picker in iOS

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Create a class named as “PLPickerRenderer.cs” and it is inherited from “Xamarin.Forms.Platform.iOS.PickerRenderer”.
  2. Then create a method “UpdatePickerPlaceholder” and copy the below code in the custom renderer class.
    void UpdatePickerPlaceholder()
    {
        if (picker == null)
            picker = Element as PLPicker;
        if (picker.Placeholder != null)
            Control.Placeholder = picker.Placeholder;
    }
  3. Call this method, in the OnElementChanged method and OnElementPropertyChanged method when the placeholder property changes.
  4. You can find the full coding part for “PLPickerRenderer.cs” below for Android.
    [assembly: ExportRenderer(typeof(PLPicker), typeof(PLPickerRenderer))]
    namespace PickerPlaceholder.iOS
    {
        public class PLPickerRenderer: PickerRenderer
        {
            PLPicker picker = null;
            protected override void OnElementChanged(ElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    picker = Element as PLPicker;
                    UpdatePickerPlaceholder();
                    if (picker.SelectedIndex <= -1)
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
            protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                base.OnElementPropertyChanged(sender, e);
                if (picker != null)
                {
                    if (e.PropertyName.Equals(PLPicker.PlaceholderProperty.PropertyName))
                    {
                        UpdatePickerPlaceholder();
                    }
                }
            }
    
            void UpdatePickerPlaceholder()
            {
                if (picker == null)
                    picker = Element as PLPicker;
                if (picker.Placeholder != null)
                    Control.Placeholder = picker.Placeholder;
            }
        }
    }

Step 5: Implementation of Custom Picker Control

In this step, we will create a custom renderer in iOS for PLPicker created in “Step 2”.

  1. Open created Xamarin.Forms Page, in my case “MainPage” and add the custom control picker with Placeholder property.
  2. Open your MainPage.xaml file and add the custom control as shown in below.
    <local:PLPicker Placeholder="Placeholder"
                    Title="Title"
                    TitleColor="Blue"
                    x:Name="plpicker"
                    Grid.Row="2"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"/>
  3. Then add buttons with clicked events to change selected index as 1 and -1 for the custom picker.
    <Button Text="PLPicker:Set Index 1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex1Clicked"
            Grid.Row="3"
            Grid.Column="0"/>
    
    <Button Text="PLPicker:Set Index -1"
            HorizontalOptions="Center"
            VerticalOptions="Center"
            Clicked="PLPIndex2Clicked"
            Grid.Row="3"
            Grid.Column="1" />
  4. Create an event for setting the selected index for picker as like below.
    private void PLPIndex1Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = 1;
    }
    
    private void PLPIndex2Clicked(object sender, EventArgs e)
    {
        plpicker.SelectedIndex = -1;
    }

Output:

Download Code

You can download the code from GitHub. If you have doubt, feel free to post comment. If you like this article and is useful to you, do like, share the article & star the repository on GitHub.