Scan Credit Cards with Xamarin.Forms

Hi Guys,

Today, I am going teach you about how to add CreditCard scanning feature to your mobile app.

If you have used the Uber mobile app, then you already know what it is.

Uber-Paytm

This is a very user-friendly and must needed feature in payment related Apps. It will make user to easily scan his credit card with mobile camera and fill the details needed for the payment.

Let’s see how to create this with Xamarin.Forms … 🙂

  1. Create a project with Xamarin.Forms

Screen Shot 2017-03-09 at 2.29.57 PM

2. Create a HomePage and set it as the MainPage in App.xaml

Screen Shot 2017-03-09 at 2.37.12 PM

3. Add Card.iO package to .Droid and .iOS projects from Nuget.

Screen Shot 2017-03-09 at 2.31.42 PM

Screen Shot 2017-03-09 at 2.32.36 PM

As you see here, we are using Card.iO for scanning. Its a free and open source library. You can get more informations from https://www.card.io .

4. Now lets create a dependancy service like below.

  • ICardService.cs in PCL project
  • CardService.cs  in  .Droid project
  • CardService.cs  in .iOS project

Screen Shot 2017-03-09 at 2.40.48 PM.png

ICardService.cs in PCL

namespace CardApp
{
    public interface ICardService
    {
        void StartCapture();

        string GetCardNumber();

        string GetCardholderName();
    }
}

CardService.cs in .iOS

using System;
using Card.IO;
using CardApp.iOS;
using UIKit;
using Xamarin.Forms;

[assembly: Dependency(typeof(CardService))]
namespace CardApp.iOS
{
    public class CardService : CardIOPaymentViewControllerDelegate, ICardService
    {
        private UIViewController rootViewController;
        private CreditCardInfo cardInfo;

        public void StartCapture()
        {
            InitCardService();
            var paymentViewController = new CardIOPaymentViewController(this);
            rootViewController.PresentViewController(paymentViewController, true, null);
        }

        public string GetCardNumber()
        {
            return (cardInfo != null) ? cardInfo.CardNumber : null;
        }

        public string GetCardholderName()
        {
            return (cardInfo != null) ? cardInfo.CardholderName : null;
        }

        private void InitCardService()
        {
            // Init rootViewController
            var window = UIApplication.SharedApplication.KeyWindow;
            rootViewController = window.RootViewController;
            while (rootViewController.PresentedViewController != null)
            {
                rootViewController = rootViewController.PresentedViewController;
            }
        }

        public override void UserDidCancelPaymentViewController(CardIOPaymentViewController paymentViewController)
        {
            Console.WriteLine(Scanning Canceled!);
        }

        public override void UserDidProvideCreditCardInfo(CreditCardInfo cardInfo, CardIOPaymentViewController paymentViewController)
        {
            if (cardInfo == null)
            {
                Console.WriteLine(Scanning Canceled!);
            }
            else 
            {
                this.cardInfo = cardInfo;
            }

            paymentViewController.DismissViewController(true, null);
        }
    }
}


CardService.cs in .Droid

using Android.App;
using Android.Content;
using Card.IO;
using CardApp.Droid;
using Xamarin.Forms;

[assembly: Dependency(typeof(CardService))]
namespace CardApp.Droid
{
    public class CardService : ICardService
    {
        private Activity activity;

        public void StartCapture()
        {
            InitCardService();

            var intent = new Intent(activity, typeof(CardIOActivity));
            intent.PutExtra(CardIOActivity.ExtraRequireExpiry, true);
            intent.PutExtra(CardIOActivity.ExtraRequireCvv, true);
            intent.PutExtra(CardIOActivity.ExtraRequirePostalCode, false);
            intent.PutExtra(CardIOActivity.ExtraUseCardioLogo, true);

            activity.StartActivityForResult(intent, 101);
        }

        public string GetCardNumber()
        {
            return (InfoShareHelper.Instance.CardInfo != null) ? InfoShareHelper.Instance.CardInfo.CardNumber : null;
        }

        public string GetCardholderName()
        {
            return (InfoShareHelper.Instance.CardInfo != null) ? InfoShareHelper.Instance.CardInfo.CardholderName : null;
        }

        private void InitCardService()
        {
            // Init current activity
            var context = Forms.Context;
            activity = context as Activity;
        }
    }

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

        public CreditCard CardInfo { get; set; }

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

MainActivity.cs  in .Droid

Add following method after OnCreate in MainActivity.cs

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            if (data != null)
            {
                // Be sure to JavaCast to a CreditCard (normal cast wont work)      
                InfoShareHelper.Instance.CardInfo = data.GetParcelableExtra(CardIOActivity.ExtraScanResult).JavaCast<CreditCard>();
            }
            else
            {
                Console.WriteLine(Scanning Canceled!);
            }
        }

Screen Shot 2017-03-09 at 5.31.49 PM

Save all.

Now our CardService is ready to use.

Before use it we have to set Camera access permission in iOS and Android.

5. Set access permissions needed for CardService.

iOS

Add a new Entry “Privacy – Camera Usage Description” in info.plist

Screen Shot 2017-03-09 at 3.10.10 PM

Android

Add following permission and configs to AndroidManifest.xml

<usessdk android:minSdkVersion=15 />
    <usespermission android:name=android.permission.ACCESS_NETWORK_STATE />
    <usespermission android:name=android.permission.INTERNET />
    <usespermission android:name=android.permission.CAMERA />
    <usespermission android:name=android.permission.VIBRATE />
    <application android:label=CardApp>
        <activity android:name=io.card.payment.CardIOActivity android:configChanges=keyboardHidden|orientation />
        <activity android:name=io.card.payment.DataEntryActivity />
    </application>

Screen Shot 2017-03-09 at 5.40.16 PM

6. Now add a button to HomePage and set an event handler

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=CardApp.HomePage>
    <ContentPage.Content>
        <Button Clicked=onScanCard HorizontalOptions=CenterAndExpand VerticalOptions=CenterAndExpand WidthRequest=200 Text=Scan my Card TextColor=White BackgroundColor=Purple/>
    </ContentPage.Content>
</ContentPage>

In code behind:

using System;
using Xamarin.Forms;

namespace CardApp
{
    public partial class HomePage : ContentPage
    {
        public HomePage()
        {
            InitializeComponent();
        }

        private void onScanCard(object sender, EventArgs e)
        {
            DependencyService.Get<ICardService>().StartCapture();
        }
    }
}

7. Now compile and run on iOS / Android:

IMG_2685          IMG_2684

Done.

Source code is available in https://github.com/hiranpeiris/CardApp

Happy coding… 🙂

Social share with Xamarin.Forms

Hi Guys,

Today, I am going to teach you about Social sharing with Xamarin.Forms.

Technically, there is no inbuilt class or method to perform a social share  in Xamarin.Forms.

So, How we are going to do this.

Dependancy services ?

Yes… 🙂 that’s the only way…

Lets create.

  1. Create a Xamarin.Forms project.

Screen Shot 2017-03-08 at 12.04.16 PM

 

2. Create a HomePage and set it as the MainPage in App.xaml.

Screen Shot 2017-03-08 at 12.08.24 PM

 

3. Create following classes.

  • IShareService.cs in PLC project
  • ShareService.cs in .Droid project
  • ShareService.cs in .iOS project

Screen Shot 2017-03-08 at 12.22.12 PM

IShareService.cs

namespace SocialApp
{
    public interface IShareService
    {
        void SharePageLink(string link);
    }
}

 

ShareService.cs   in .Droid

using Android.App;
using Android.Content;
using Xamarin.Forms;
using SocialApp.Droid;

[assembly: Dependency(typeof(ShareService))]
namespace SocialApp.Droid
{
    public class ShareService : IShareService
    {
        public void SharePageLink(string url)
        {
            var context = Forms.Context;
            Activity activity = context as Activity;

            Intent share = new Intent(Intent.ActionSend);
            share.SetType(text/plain);
            share.AddFlags(ActivityFlags.ClearWhenTaskReset);
            share.PutExtra(Intent.ExtraSubject, Brusselslife);
            share.PutExtra(Intent.ExtraText, url);

            activity.StartActivity(Intent.CreateChooser(share, Share link!));
        }
    }
}

 

ShareService.cs   in .iOS

using Foundation;
using UIKit;
using Xamarin.Forms;
using SocialApp.iOS;

[assembly: Dependency(typeof(ShareService))]
namespace SocialApp.iOS
{
    public class ShareService : IShareService
    {
        public void SharePageLink(string url)
        {
            var window = UIApplication.SharedApplication.KeyWindow;
            var rootViewController = window.RootViewController;

            var activityViewController = new UIActivityViewController(new NSString[] { new NSString(url) }, null);
            activityViewController.ExcludedActivityTypes = new NSString[] {
                UIActivityType.AirDrop,
                UIActivityType.Print,
                UIActivityType.Message,
                UIActivityType.AssignToContact,
                UIActivityType.SaveToCameraRoll,
                UIActivityType.AddToReadingList,
                UIActivityType.PostToFlickr,
                UIActivityType.PostToVimeo,
                UIActivityType.PostToTencentWeibo,
                UIActivityType.PostToWeibo
            };

            rootViewController.PresentViewController(activityViewController, true, null);
        }
    }
}

 

Save all.

Now our SocialShare service is ready for use.

 

3.  Add a button with event handler in HomePage.

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=SocialApp.HomePage>
    <ContentPage.Content>
        <Button Clicked=OnShare HorizontalOptions=CenterAndExpand VerticalOptions=Center WidthRequest=200 Text=Share TextColor=White BackgroundColor=Purple/>
    </ContentPage.Content>
</ContentPage>

 

using System;
using Xamarin.Forms;

namespace SocialApp
{
    public partial class HomePage : ContentPage
    {
        public HomePage()
        {
            InitializeComponent();
        }

        private void OnShare(object sender, EventArgs e)
        {
            string shareLink = http://hiranpeiris.com;
            DependencyService.Get<IShareService>().SharePageLink(shareLink);
        }
    }
}

 

You can share,

Link, Youtube Video, Picture url or Text.

 

4. Compile and run on Android.

Screenshot_1488956879          The+Hindu+Android+App-Makes+sharing+easy-2.png

 

5. Compile and run on iOS.

Screen Shot 2017-03-08 at 12.49.57 PM       tQtSC

 

Done… 🙂

Source code available in https://github.com/hiranpeiris/SocialApp

Happy coding… 🙂

How to add a custom Bindable Property to Xamarin.Forms control

Hi Guys,

Today, I am going to teach you about adding custom Bindable properties to Built in controls in Xamarin.Forms.

Recently, I have got a requirement to create a Picker with ItemsSource property. The underline idea was to use MVVM model with Picker contols. In other words, the developer wanted to bind his List object as a property from ViewModel class to XAML binding on the Page. Its a really solid way of organizing the code. In fact, the MVVM is the most recommended and standard approach when comes to the World of Xamarin.

But unfortunately,  the Picker control doesn’t have a ItemsSource property by defaluty. But controls like ListView does.

Ok. here is the solution, what I have given to that developer…

Create a Custom Picker with ItemsSource Bindable property.

  1. Create your custom picker class

using System.Collections.Generic;
using Xamarin.Forms;

namespace FDNet
{
    public class OutletPicker : Picker
    {
        public static readonly BindableProperty ItemSourceProperty = BindableProperty.Create(nameof(ItemSource), typeof(List<string>), typeof(OutletPicker), null);

        public List<string> ItemSource
        {
            get
            {
                return (List<string>)GetValue(ItemSourceProperty);
            }
            set
            {
                SetValue(ItemSourceProperty, value);
            }
        }

        protected override void OnPropertyChanged(string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            if (propertyName == nameof(ItemSource))
            {
                this.Items.Clear();
                if (ItemSource != null)
                {
                    foreach (var item in ItemSource)
                    {
                        this.Items.Add(item);
                    }
                }
            }
        }
    }
}

2. Add XAML reference variable to the Page.

xmlns:local=clrnamespace:FDNet;assembly=FDNet

3. Add the control and bind the property.

<local:OutletPicker Title=Select ItemSource={Binding Outlets} HorizontalOptions=Center WidthRequest=300 />

Now you can see our custom bindable property   ItemSource={Binding Outlets})

4. Demo.

Outlets = new List<string> { 4G LTE, 4G Broadband, Fiber connection };

<local:OutletPicker Title=Select ItemSource={Binding Outlets} HorizontalOptions=Center WidthRequest=300 />

select

Ok Guys…

Happy coding… 🙂

What is a Dependency Service in Xamarin.Forms ?

Hi Guys,

Today, I am going to teach you about Dependency Services in Xamarin.Forms.

What is a dependency service ?

Xamarin.Forms is a PCL package. So you cannot access all the native APIs on each platforms.For an example, Can you show a Toast message in Android from your PCL project ?

Note: PCL project is the place where you define your UI in Xamarin.Forms App.

Answer is NO…

If NO then whats the solution ?

The solution is to write a Dependency Service.

Dependency Service is a feature in Xamarin.Forms where you can execute/call/invoke a function/method in the native platform.

battery_diagram

As you see in the above diagram, there is a Dependency Service written to get the battery status from Native platform to PCL code.

Now, Lets write a small Dependency Service… 🙂

  1. Create a project called DSToast.

screen-shot-2017-02-18-at-8-57-17-pm

2. Create a HomePage and set it as the MainPage in App.xaml.

screen-shot-2017-02-18-at-9-01-26-pm

3. Add a button to HomePage and set the click event handler.

HomePage.xaml

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=DSToast.HomePage>
    <ContentPage.Content>
        <Button Text=Show Message Clicked=OnClick HorizontalOptions=Center VerticalOptions=Center/>
    </ContentPage.Content>
</ContentPage>

HomePage.xaml.cs

using System;
using Xamarin.Forms;

namespace DSToast
{
    public partial class HomePage : ContentPage
    {
        public HomePage()
        {
            InitializeComponent();
        }

        private void OnClick(Object sender, EventArgs e)
        { 
            
        }
    }
}

4. Now create following dependency interface and classes.

  • INativeMsg.cs in PCL project.
  • NativeMsg.cs in Android.
  • NativeMsg.cs in iOS.

screen-shot-2017-02-18-at-9-12-48-pm

INativeMsg.cs in PCL project

namespace DSToast
{
    public interface INativeMsg
    {
        void ShowMsg(string msg);
    }
}

NativeMsg.cs in .Droid project

using DSToast.Droid;
using Xamarin.Forms;
using Android.Widget;

[assembly: Dependency(typeof(NativeMsg))]
namespace DSToast.Droid
{
    public class NativeMsg : INativeMsg
    {
        public void ShowMsg(string msg)
        {
            Toast.MakeText(Forms.Context, msg, ToastLength.Long).Show();
        }
    }
}

NativeMsg.cs in .iOS project

using DSToast.iOS;
using Xamarin.Forms;
using UIKit;

[assembly: Dependency(typeof(NativeMsg))]
namespace DSToast.iOS
{
    public class NativeMsg : INativeMsg
    {
        public void ShowMsg(string msg)
        {
            var alert = new UIAlertView(Message, msg, null, OK,null);
            alert.Show();
        }
    }
}

Now, our Dependency Service is ready to use. Let’s use… 🙂

5. Go to click event handler in PCL project and call the Dependency Service like below.

DependencyService.Get<INativeMsg>().ShowMsg(I am a Native Message!);

screen-shot-2017-02-18-at-9-34-27-pm

6. Now compile and run on each platforms.

Android:

screenshot_20170218-212312

iOS:

simulator-screen-shot-feb-18-2017-9-30-05-pm

Isn’t that cool ?   🙂

Source code available in https://github.com/hiranpeiris/Xamarin-DSToast

Happy coding… 🙂

Custom TabBar Theme with Xamarin.Forms

Hi Guys,

Today, I am going to teach you how to create a custom theme for TabBar App with Xamarin.Forms. As you see in the above image, its looks nice when you create your own theme rather than default look and feel.

Lets create… 🙂

screen-shot-2017-02-18-at-7-32-26-am

Note: In Xamarin.Forms TabBarPage is defined as TabbedPage.

  1. Add a TabbedPage and name it as MyTabBarPage…

MyTabBarPage.xaml

<?xml version=1.0 encoding=UTF8?>
<TabbedPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=TabBarTheme.MyTabBarPage>

</TabbedPage>

MyTabBarPage.xaml.cs

using Xamarin.Forms;

namespace TabBarTheme
{
    public partial class MyTabBarPage : TabbedPage
    {
        public MyTabBarPage()
        {
            InitializeComponent();
        }
    }
}

2. Set it as the MainPage in App.xaml.cs

screen-shot-2017-02-18-at-8-00-24-am

3. Create following Page classes.

  • PopularPage
  • NewPage
  • SearchPage
  • MyMusicPage

screen-shot-2017-02-18-at-8-06-10-am

4. Now copy your tab icons to .Droid and .iOS resources folders.

iOS:

screen-shot-2017-02-18-at-8-08-44-am

Android:

screen-shot-2017-02-18-at-8-15-04-am

6. Add xaml prefix to MyTabBarPage.xaml

xmlns:local=clrnamespace:TabBarTheme;assembly=TabBarTheme

7. Add your pages to MyTabBarPage.xaml

<?xml version=1.0 encoding=UTF8?>
<TabbedPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:local=clrnamespace:TabBarTheme;assembly=TabBarTheme xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=TabBarTheme.MyTabBarPage>
    <NavigationPage Title=Popular Icon=popular.png BarTextColor=White BarBackgroundColor=#bc4b4b>
        <x:Arguments>
            <local:PopularPage Title=Popular />
        </x:Arguments>
    </NavigationPage>
    <NavigationPage Title=New BarTextColor=White Icon=newr.png BarBackgroundColor=#bc4b4b>
        <x:Arguments>
            <local:NewPage Title=New Releases />
        </x:Arguments>
    </NavigationPage>
    <NavigationPage Title=Search BarTextColor=White Icon=search.png BarBackgroundColor=#bc4b4b>
        <x:Arguments>
            <local:SearchPage Title=Search />
        </x:Arguments>
    </NavigationPage>
    <NavigationPage Title=My Music BarTextColor=White Icon=music.png BarBackgroundColor=#bc4b4b>
        <x:Arguments>
            <local:MyMusicPage Title=My Music />
        </x:Arguments>
    </NavigationPage>
</TabbedPage>

7. Now compile and run on Android.

screenshot_20170218-082903

Ooops…. 😦

What’s happen ?

Our navigation bar theme  is not matching with the native tabs theme.

So, lets fix it…

8. #bc4b4b is the color we have used in navigation bar in the Forms/PCL project. Lets set the same color for native UI controls from the .Droid project.

Go to Resources > values > styles.xml file in .Droid project

screen-shot-2017-02-18-at-8-36-36-am

Then, replace native style colors with our theme color (#bc4b4b).

<?xml version=1.0 encoding=UTF8?>
<resources>
    <style name=MyTheme parent=MyTheme.Base>
    </style>
    <!– Base theme applied no matter what API –>
    <style name=MyTheme.Base parent=Theme.AppCompat.Light.DarkActionBar>
        <!–If you are using revision 22.1 please use just windowNoTitle. Without android:–>
        <item name=windowNoTitle>true</item>
        <!–We will be using the toolbar so no need to show ActionBar–>
        <item name=windowActionBar>false</item>
        <!– Set theme colors from http://www.google.com/design/spec/style/color.html#colorcolorpalette–>
        <!– colorPrimary is used for the default action bar background –>
        <item name=colorPrimary>#bc4b4b</item>
        <!– colorPrimaryDark is used for the status bar –>
        <item name=colorPrimaryDark>#bc4b4b</item>
        <!– colorAccent is used as the default value for colorControlActivated
         which is used to tint widgets –>
        <item name=colorAccent>#bc4b4b</item>
        <!– You can also set colorControlNormal, colorControlActivated
         colorControlHighlight and colorSwitchThumbNormal. –>
        <item name=windowActionModeOverlay>true</item>
        <item name=android:datePickerDialogTheme>@style/AppCompatDialogStyle</item>
    </style>
    <style name=AppCompatDialogStyle parent=Theme.AppCompat.Light.Dialog>
        <item name=colorAccent>#bc4b4b</item>
    </style>
</resources>

9. Set a dark version of the same color for the Control Activated state.

<item name=colorPrimaryDark>#963c3c</item>

I am using #963c3c as a dark version of #bc4b4b.

screen-shot-2017-02-18-at-9-21-42-am

10. Now compile and run.

screenshot_20170218-085221

Wow, finally got it… 🙂   Isn’t that cool… ?

11. Now compile and run on iOS.

simulator-screen-shot-feb-18-2017-8-55-47-am

See, same problem happen to iOS now.

Lets fix that also.

Go to AppDelegate.cs in .iOS project and copy following code before line LoadApplication(new App());.

// Set app theme
UITabBar.Appearance.BarTintColor = UIColor.FromRGB(188, 75, 75);
UITabBar.Appearance.TintColor = UIColor.White;
UIProgressView.Appearance.TintColor = UIColor.FromRGB(188, 75, 75);

Note: UIColor.FromRGB(188, 75, 75) is the UIColor RGB version of #bc4b4b .

You can calculate it from http://uicolor.xyz/#/hex-to-ui

screen-shot-2017-02-18-at-9-19-45-am

12. Now, compile and run again.

simulator-screen-shot-feb-18-2017-9-03-38-am

Now looks better. But, still battery, carrier, time informations are in black color. It’s not matching with our theme. we have tom make it white color.

13. Open info.plist in .iOS project from a text editor and add following code.

<key>UIViewControllerBasedStatusBarAppearance</key>

<false/>

e.g:

screen-shot-2017-02-18-at-9-13-06-am

Save and close.

14. Now clean, rebuild and run again.

simulator-screen-shot-feb-18-2017-9-16-25-am

Finally we got it.

Cheers… 🙂

Sourcecode available in https://github.com/hiranpeiris/Xamarin-TabBarTheme

Happy coding… 🙂

How to write a custom TextField / Entry in Xamarin Forms

Hi Guys,
Today i am going to teach you about how to create a custom TextField in Xamarin Forms.
In Xamarin, we called it as custom renderers.
Custom renderers ?
Hmmm…
It seems not much familiar to people who are new to Xamain Forms App developments. Don’t worry, my ambition is to teach you from the beginning. Before going to write a custom renderer, we have to understand how Xamarin Forms work.

Lets say, that we have created a button in a Xamarin.Forms Page.

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=MyApp.HomePage>
    <ContentPage.Content>
        <Button Text=My Button/>
    </ContentPage.Content>
</ContentPage>

Xamarin compiler will handle this code according to following diagram.

image

As you see in the diagram, your button will be rendered on each of platforms via platform specific renderer classes. These are defined in Xamarin.Forms package. This is how Xamarin Forms work.

Now guess, what we have to do in order to create a custom control.

Inheritance ?

Exactly… 🙂

Create our own renderer class which is inherited from Xamarin.Forms renderer class.

Thats the plan… 🙂

Lets create…

Note: In Xamarin.Forms, TextField is defined as Entry.

Lets create an Entry with a BoxBorder…

screen-shot-2017-02-16-at-3-30-19-pm

Create a HomePage and set it as the main page

screen-shot-2017-02-16-at-3-39-54-pm

Create following classes,

  1. Create BoxBorderEntry class in BoxEntry project
  2. Create BoxBorderEntryRenderer class in BoxEntry.Droid project
  3. Create BoxBorderEntryRenderer class in BoxEntry.iOS project

screen-shot-2017-02-16-at-4-03-37-pm

BoxBorderEntry.cs

using Xamarin.Forms;

namespace BoxBorderEntry
{
    public class BoxBorderEntry : Entry
    {
        public BoxEntry()
        {
        }
    }
}

BoxBorderEntryRenderer.cs   –  In iOS

using BoxEntry;
using BoxEntry.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(BoxBorderEntry), typeof(BoxBorderEntryRenderer))]
namespace BoxEntry.iOS
{
    public class BoxBorderEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.TextColor = UIColor.Black;
                Control.Layer.BorderColor = UIColor.Black.CGColor;
                Control.Layer.BorderWidth = 3.0f;
            }
        }
    }
}

BoxBorderEntryRenderer.cs  – In Droid

using BoxEntry;
using BoxEntry.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(BoxBorderEntry), typeof(BoxBorderEntryRenderer))]
namespace BoxEntry.Droid
{
    public class BoxBorderEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.SetBackgroundResource(Resource.Drawable.BoxBorder);
            }
        }
    }
}

BoxBorder.xml  –  Create a style xml for Android in Resources -> drawable folder

screen-shot-2017-02-16-at-4-11-30-pm

<?xml version=1.0 encoding=utf8?>
<shape xmlns:android=http://schemas.android.com/apk/res/android android:thickness=0dp android:shape=rectangle>
    <stroke android:width=3dp android:color=#000000 />
</shape>

Save all.

Now our BoxBorderEntry is ready to use… 🙂

Shall we  ?

Before we use our custom control, we have to make a reference variable in the Xamal code.

xmlns:local=clrnamespace:BoxEntry;assembly=BoxEntry

This is how you do it,

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:local=clrnamespace:BoxEntry;assembly=BoxEntry xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=BoxEntry.HomePage>
    <ContentPage.Content>
        <local:BoxBorderEntry Placeholder=Your name here... WidthRequest=200 HorizontalOptions=Center VerticalOptions=Center/>
    </ContentPage.Content>
</ContentPage>

Finally compile and run on iOS / Android.

Android:

screenshot_1487252203

iOS:

screen-shot-2017-02-16-at-7-17-44-pm

Happy coding… 🙂

Source code available in https://github.com/hiranpeiris/Xamarin-Custom-ENTRY