Category Archives: Programming

XAMVVM-01 A real walk-through of Xamarin.UITest with Xamarin.Forms!

Let’s take a chilled out walk through adding Xamarin.UITests to your Xamarin.Forms project! 😉

When I said chilled out, I meant literally a chill, no-fuss walk through adding UITests for your Xamarin.Forms project solution. There’s many articles and tutorials out there regarding this, but when I first started I couldn’t find a clear enough guide to begin with for myself, so I was stumbling around in confusion here and there until I self-learned a proper foundation. That’s why I thought of writing this post.

This is an attempt of sharing my experience and intuition of how to architect a better UITest structure for your Xamarin.Forms Solution helping you to get a clear and easy head start!

So I’m not gonna get into extreme baby steps, or details, but a clear fuss-free hands-on guide for starting off with your UITests, which I hope would give you a clear picture and understand of the whole shabang! After all I’m all about that solid project architecture!

Why UITests?

Hey, if you’re looking for a serious intro, please Google! I don’t like repetition of content lol.

Xamarin.UITests comes in handy when you want to have consistent assurance of the actual functionality of the app with the UI behaviour included. And between you and me, I actually love watching UITests being executed on Devices and Simulators, seeing you app actually being used like a human, giving you a whole feedback loop of the UI behaviour , is just an incredible experience! 😉

 

Let’s get started..

Just for the showcase of this awesomeness, I created a little App, which is called Textpad, where you simple take notes or texts of whatever you feel like. 😉 A very simple out of the box Xamarin.Forms app, and fully MVVM architectured code base with Prism. I named the solution as “XFWithUITest” just for this demo.

Whatever the default template of the Xamarin.UITest has provided, I have done several changes to it here and there for the clarity and of the code base as you will see in this article.

So I’m gonna walk you through a clean and well-structured manner of adding Xamarin.UITests to your project solution.

You can take a little sneak peak at it over here in my github repo:
XAMVVM-Playground/XFWithUITest

Structure is important!

There’s many ways to structure a UITest, but I like a clean separation of the elements in any solution architecture. Like here we’re going to separate our Tests from the actual Host projects.

So first, for the name of separation let’s add a Folder called “Tests” in your Xamarin.Forms solution. Yes, that’s the way to start!

Then let’s create our Xamarin.UITest project, right-click on the “Tests” folder in the VS Solution Explorer and go to Test tab and select Xamarin.UITest Cross-Platform Test Project!

Also pay extra attention to the Name and Location value for our UITest project. Append “.UITest” at the end of your project name. As of the location, make sure to add the path along with the “Tests” folder that we created above.

Next create a new Folder inside of that project called “Tests”, yes another one, which is where we’re actually placing our tests! Also create a new class called SetupHooks, which is where we’ll maintain all the hooks that are needed for our tests. (I’ll get into details for this in a later step)

Now it should look something like this!

Nothing more.

Delete anything else that’s unnecessary or not seen above! 😉

Off to next step!

Don’t forget the nugets!

Make sure all the necessary nuget packages are in place, which is just basically the following 3 nugets! yep that’s it!

Pay very careful attention here to the version of NUnit version 2.6.4, which is the minimum NUnit version supported by Xamarin.UITest as of today. (01/11/2018)

The deal with AppInitializer!

Now this right here is where your Tests will be firing up the app’s execution. There are many ways to structure this class and its functionality, but here’s my way…

This class comes pre-populated when you first create the UITest project, but I have made some changes of my own for the clarity of the code.

As you can see I’m passing in an extra boolean parameter “clearData”, which is to execute a clean instance of my App for testing.

I’m using the InstalledApp() call to load the Android and the iOS apps from the simulators, also I’m enabling the EnableLocalScreenshots() to get actual screenshots of my test instances as I wish. Yeah the fact that you can automatically capture screenshots during testing even when you run locally is really cool feature of Xamarin.UITests! 😉

Now instead of getting a hook on the InstalledApp(), you could use the path to the APK or IPA file using the ApkPath() or AppBundle() respective for Android and iOS, which is totally up to your choice.

Then I’m passing in the AppDataMode parameter according to my choosing of the “clearData” value.

SetupHooks holds the instances!

Remember earlier I created a class called SetupHooks? let’s set it up now!

public class SetupHooks
{
      public static IApp App { get; set; }

      public static Platform Platform { get; set; }
}

 

During UITests execution we’re holding a singular instance of the app in memory, which we’re calling through UITest’s functions to perform many operations, so to simplify that, here we’re holding a public static instance of the IApp and Platform object to be used in our Test cases.

Pretty neat eh! 😀

Let’s write the Tests!

Create a class called AppTests, which is where we’re going to place the Test fire up code and the rest of the tests for now!

namespace XFWithUITest.UITest.Tests
{
    [TestFixture(Platform.Android)]
    //[TestFixture(Platform.iOS)]
    public class AppTests
    { 
        public AppTests(Platform platform)
        {
            SetupHooks.Platform = platform;
        }

        [SetUp]
        public void BeforeEachTest()
        {
            SetupHooks.App =  
            AppInitializer.StartApp(SetupHooks.Platform, true);
        }

        [Test]
        ...
	// test cases begin here...
		
	}
}

 

There I have added the TestFixture attributes as required by NUnit to identify our tests, and notice how I have commented out the iOS platform, to show you that you could stick to one platform at a time for your ease of testing, instead of seeing failed tests in the Test Runner window! 😉

[SetUp] is where your Tests will initialize the actual App instance, thus retrieving a hook to the app’s instance for our Test cases to use.

You can see how I’m tying up the SetupHooks – Platform and App instances, through the initiation of the AppTests.

AppInitializer.StartApp(SetupHooks.Platform, true);

This gives a clean instance of the app for our tests cases to use, and up on your wish you could pass in “false” to the same method and get a data persisted instance of the app at anytime, anywhere in your tests! 😉

Now you’re all set to start writing your UITests, but before we begin I need you to check up on something else!

AutomationId for everything!

Whatever the UI element you need to get a hook on to or get a reference of, be it a Page, Button, Layout even a Label, you need to add a value to its AutomationId.

And make sure every AutomationId in a given Page context is unique for every element, otherwise the look up function will return all the elements that matches the given Id, which could lead to confusion in your tests 😉

IApp interface functions!

The Xamarin.UITest.IApp interface provides a whole bunch of functionalities for the app for us to play around with in order to execute our test scenarios.

Take a look here, Xamarin.UITest.IApp to see the list of powerful functions we can use. To name a few are Tap, Swipe, Scroll, WaitForElement and etc, to be performed on any given UI Element on the screen.

So now all you need to do is get a hook on any given element..

Getting a hook on an Element…

There’s several ways of doing this, most common is by the AutomationId of the Element

SetupHooks.App.Tap(c => c.Marked("Button1"))

Another is by the value of an Element’s property,

SetupHooks.App.Tap(c => c.Text("Click this Button!"))

Or you could do by even the Class name of the element. Choice is completely yours, pick the one best suited for your test case.

How to write a Test?

Now this is the coolest part, Xamarin.UITest allows us to get hooks on to UI Elements of the running App, then we perform actions on those elements and wait for the results and check if it resulted as expected through assertion using NUnit.

So its basically a little dance between Xamarin.UITest and NUnit Assertion! 😉

As a standard keep in mind to append “Test” at the end of each of your Test cases.

As you can see above I’m first waiting for the HomePage to appear, then I’m asserting it through NUnit. Then I look for the Label with “Hey there, Welcome!” text!

Action and Result, simple as that! 😀

Some advanced bits…

Here’s some advanced bits that could come in handy!

Getting the number of elements in a ListView
SetupHooks.App.Query(c => c.Marked("TextListView").Child()).Length
Getting an element in a ListView
Func<AppQuery, AppQuery> itemInListView = null;

if (SetupHooks.Platform == Platform.Android)
     itemInListView = 
     x => x.Class("ViewCellRenderer_ViewCellContainer").Index(0);
else if (SetupHooks.Platform == Platform.iOS)
     itemInListView = 
     x => x.Marked("<your listview automationId>").Index(0);

// change the index parameter to get the item you wish
Opening Context Menu in a ListView item
// pop up the Context menu in ListView item
if (SetupHooks.Platform == Platform.Android)
      SetupHooks.App.TouchAndHold(firstCellInListView);
else if (SetupHooks.Platform == Platform.iOS)
      SetupHooks.App.SwipeRightToLeft(firstCellInListView);
Enter Text into an Entry or Editor
SetupHooks.App.EnterText(
c => c.Marked("TextTitleEditor"), whateverYourText);
Wait for an element to disappear
SetupHooks.App.WaitForNoElement(c => c.Text("This label text"));

// either by Text or Marked as should work
Restarting the app anywhere…
// restarting app, persisting state

SetupHooks.App = AppInitializer.StartApp(SetupHooks.Platform, false);

Check out more here in this awesome git page: XamarinTestCloudReference

REPL is your tool!

Yes start using the REPL command line to see how your App’s UI is actually rendered by the native platform at any given execution time. Simply call this anywhere you wish in the UITests steps,

App.REPL();

And you’ll be presented with a CLI which will help you see the whole UI tree of the screen. Simply type “tree” in the CLI and you’re good!

Structuring the tests..

Now there’s many ways to structure all the test cases and scenarios, and there’s no strict standard way that should be followed, but whatever you’re comfortable or fits your project is totally fine and the choice is yours!

You could include all your Test cases in the AppTest class itself, or you can break them into separate classes regarding the Page, or the functionality type.

So for this demo I’m keeping all my UITest cases in the AppTest class itself.

Running the UITests locally!

Well now that we have structured the architecture, here’s the time for actual firing things up and you’ve got couple of things to remember!

You can run your Android Tests on Simulator and Device directly without any modification as long as you provide the right APK path or the App Id.

You can run your iOS Tests only on Visual Studio for Mac, and for the device you need to pass the provisioning details, and as of simulator, you need to pass the Simulator Id.

If you’re using InstalledApp() or ConnectToApp() in your AppInitializer, then make sure the app is already deployed or running in the devices or simulator.

Also make sure to keep your Devices or Simulators or Emulators screens switched on at all times, otherwise tests will break giving a waiting exception.

That’s it!

But I’m not completely satisfied with the architecture, so let’s kick it up a notch! 😀

Little cherry on top Architecture!

Like I said before there’s many ways to construct the architecture for your Test project, one of my favourite ways is by separating the test cases by Page Scenario, which I think is a much cleaner structure.

We’re going to create a base class, “TestBase” which has the constructor initiation and BeforeEachTest setup, then create a sub classes that inherits from it representing whatever the pages we have in the App.

It should look something like this!

And don’t forget you need to add TestFixture attribute for every single sub-class!

So what you’re gonna do is take apart all the Test cases you had in one class and move them into the related pages, simply cut and paste of the methods should do! Also on top of that you could abstract another layer of shared steps that we could reuse across these Page tests. 😀

Then it should give you a clean Test output as below.

There you go, all the Tests are now nicely aligned and structured under the given Page which it associates with!

Pretty neat eh!

So this above structure of mine is somewhat more of a simplification of the Page Object Architecture which is well explained here for Xamarin.UITests: https://www.codetraveler.io/

And even in this official github sample from Xamarin uses the same similar pattern: SmartHotel.Clients.UITests

Done!

As you can see its not that hard to set up your Xamarin.Forms project with UITest once you get the basic understanding of the moving parts and keep a clear structure in your head.

Now for some of you might be experiencing some issues with Xamarin.UITest, in which case I had too when I was first starting off. Therefore I ended up writing this post sharing my experience of solving them: Getting your Xamarin UITests to actually work! So if you’re having any issues getting your Xamarin.UITests to work in Visual Studio, that post might be able to help you. 🙂

Do check out my Github repo of this post:
XAMVVM-Playground/XFWithUITest

Thus concludes my real walk-through of Xamarin.UITests with Xamarin.Forms, in which I hope you got a clear understanding of how to properly structure your project and all the moving bits and pieces that gets the job done! 😀

Share the love! 😀

Cheers!

Advertisements

Using iOS 12 OTP Security Code AutoFill in Xamarin.Forms!

Let’s try new iOS 12 Security Code AutoFill feature in Xamarin.Forms!

The new iOS 12 update has brought a whole bunch of awesome updates, although which were mostly already was available on Android years back.

One of those features is getting rid of the old annoying OTP code filling process in iOS apps, where as every time you have to insert an OTP code into the app you have to quit the app and go to the messages and copy and past the OTP manually into the app.

But with iOS 12 update they have made it easier by allowing Apps to auto read OTP messages without going back and forth into the Message app or copy and pasting. iOS now automatically suggest the top most available OTP message in the inbox for your OTP Text fields in the Keyboard suggestion bar.

(Source: beebom.com)

Well its not practically auto-read but still much convenient than before 😉 lol

What happens is that when an OTP message receives into the Message Inbox, iOS runs a simple text matching algorithm that determines if that message is a valid OTP message or not and based on that keep a track of it in the memory, then when the user clicks on the OTP AutoFill enabled text field in an app, iOS keyboard popup that OTP as a suggestion in the keyboard. So that your users can fill up the OTP into the app without leaving the app or going back into the Messaging app. Pretty convenient!

iOS 12 update in Xamarin!

Following the new iOS 12 update, Xamarin has immediately released the support for it within weeks, so make sure to update your XCode and Xamarin nuget packs, to get your hands dirty with it!

Let’s try it in Xamarin.Forms!

Since iOS 12 is now fully supported on Xamarin, we can access those features in our Xamarin.Forms projects as well, by accessing the Xamarin native project levels. So before we get started please make sure you have updated your Xamarin iOS packages.

iOS provides a new property called UITextContentType.OneTimeCode for the TextContentType property of UITextField in Xamarin.

We’re gonna do this using a custom renderer allowing us to access the UITextField’s native properties, which is the native counterpart of Xamarin.Forms.Entry in iOS.

So let’s start by creating the Custom Control: OTPAutoFillControl

/// <summary>
/// OTP AutoFill Control for Xamarin.Forms
/// </summary>
public class OTPAutoFillControl : Entry
{

}

 

Then’ let’s createthe Custom Renderer!

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

      if (e.NewElement != null)
      {
        Control.TextContentType = UITextContentType.OneTimeCode;
      }
    }
  }
}

 

There we go, setting up our Xamarin.Forms.Entry’s native counterpart UITextField for the OTP Auto-Fill feature in iOS 12.

Alright that’s it you’re all good to go.

<local:OTPAutoFillControl
	Grid.Row="2"
	FontSize="Large"
	HorizontalOptions="Center"
	Keyboard="Numeric"
	Placeholder="XXXXXX" />

 

Now use our OTPAutoFillControl anywhere in your Xamarin.Forms app, deploy to an iOS 12 Device, then retrieve an OTP message, and see the magic happens! 😉

How simple eh! 😀 yep even I was surprised at first.

Check out my github repo sample:
github.com/Xamarin-Playground/XFOTPAutoFillControl

iOS still doesn’t give out much awesome features or god-mode control of the device, but still this by far a really nice and easy to use feature from a developer’s perspective!

Few things to keep in mind!

First thing, iOS 12 – OTP Auto-Fill feature works perfectly in Xamarin Native and Xamarin.Forms because of the native magic of Xamarin. You have nothing to worry!

Then keep in mind, there’s a certain pattern of OTP messages iOS 12 supports for now, not to worry, its mostly standard ones such as below,

(Source: Apple Dev Conference WWDC 2018)

So please do keep an eye out for the OTP message structure if you run into any issues using this feature, otherwise it should work right out of the box like a charm! 😀

Now if you like to learn more about the iOS 12 developer’s update, check out their WWDC 2018 conference:

or wanna learn more of the new OTP AutoFill or Password generate in native iOS, check out these gems:

There you go!

Spread the love! 😀

Getting your Xamarin UITests to actually work! (Not thanks to Xamarin Docs)

Can’t get your Xamarin UITest to work? then this might actually help! 😉 yeah no thank you Xamarin Documentation!

Backstory?

So there I was having my Visual Studio updated to the latest version 15.8.8 and I created a fresh Xamarin.Forms project using the default template. Then I happily added the Xamarin.UITest project as well me being a TDD enthusiast.

So I wrote some code in my Xamarin.Forms project, added some pages, some simple navigation and functionality. Then I tried to run my Xamarin UITest, and surprise! I couldn’t get it to work at all.

First issue..

Everything was building nice and well, but when I tried to run the UITest, Visual Studio was annoying me with the following error in Output log.

Exception thrown: 'System.Exception' in Xamarin.UITest.dll
An exception of type 'System.Exception' occurred in Xamarin.UITest.dll but was not handled in user code
The running adb server is incompatible with the Android SDK version in use by UITest:
C:\Program Files (x86)\Android\android-sdk

You probably have multiple installations of the Android SDK and should update them or ensure that your IDE, simulator and shell all use the same instance. The ANDROID_HOME environment variable can effect this.

So I tried Debugging the UITest, and no surprise the runtime error was popping up same as above.

In utter surprise I went ahead to the Xamarin UITest documentation to see if there’s anything new that I haven’t heard before which needs to be done to get this super simple test project to run.

But nope! I had done everything as it was mentioned in the documentation with the perfect configuration in my up-to date Visual Studio and project set up already.

So what could have simply gone wrong?

After many days of researching, testing and pulling out my hair, I figured out the problem.

Xamarin.UITest version 2.2.6 (the latest to date: 26/10/2018)) does not support the latest version Android SDK Platform-Tools!

Yeah, no thank you to the Xamarin Documentation that never mentions there’s a constraint on the Xamarin.UITest supported Android SDK Platform-Tools!

Xamarin.UITest version 2.2.6 supports Android SDK Platform-Tools version 25.0.3 or lower only! (to the date: 26/10/2018))

I was actually surprised that there was no mentioning of this anywhere in the Xamarin UITest documentation! Sincerely hope they add some documentation between the support versions of Xamarin.UITest and Android SDK Platform-Tools.

Solving it!

So I went ahead and downgraded my  Android SDK Platform-Tools to version 25.0.3in my PC.

And finally got my UITest to run like a charm! 😀

Don’t you just hate it when an overhyped framework just doesn’t work as expected even after you perfectly set up everything accordingly to their documentation. 😦

Second issue..

Not only that, if you had followed the Xamarin UITest documentation and created your Xamarin.UITest project, then you may be facing the bellow error in your Error List window in Visual Studio!

This is occurring when you add the Android project reference to your Xamarin.UITest project. This actually doesn’t cause any issues on the compilation or runtime, the errors just remain there without going away.

I did a bit of digging on this issue and found out that this is a bug in Visual Studio, which has apparently been fixed in one of the previous versions in VS as Microsoft claims but its still occurring in my dev environment which has the latest version of VS 15.8.8!

Check it out here: https://github.com/MicrosoftDocs/xamarin-docs/issues/508

Since it doesn’t actually interfere in compilation or runtime, it shouldn’t really matter, but it would prevent you from adding Nuget packages to your Xamain.UITest project.

Solving it!

Simple forget what the documentation says and remove the Android project reference from your Xamain.UITest project.

There you got rid of the annoyance! 😉

Still having issues? Then these..

So if you’re still facing any issues pay attention to the following facts and give it a go!

1. Configure ANDROID_HOME environment variable in your Windows system.

Make sure you have added the User variable for ANDROID_HOME path in your Environment Variables.

2. Install the Xamarin.UITest compatible NUnit version 2.6.4 nuget in your UITest project

Make sure you have the exact version as shown above which is the NUnit version supported by Xamarin.UITest as of today.  And you’re gonna need NUnitTestAdapter verion 2.1.1 for the tests to work on Windows.

3. Make sure your AppInitializer is properly configured with apk path, or apk name.

public class AppInitializer
{
    public static IApp StartApp(Platform platform)
    {
        if (platform == Platform.Android)
        {
            return ConfigureApp.Android
                .InstalledApp("com.udara.xfwithuitest")
                .StartApp(AppDataMode.Clear);
        }

        return ConfigureApp.iOS
                .InstalledApp("com.udara.xfwithuitest")
                .StartApp(AppDataMode.Clear);
    }
}

 

There are several ways to configure your APK or IPA file, either with the name or the full file path. Make sure you have chosen best way possible for you. Above is how I have configured mine, which depends on the already installed APK or the IPA file in the device.

4. Don’t forget to configure Calabash to run the UITest for iOS

This is essential if you’re trying to get it to run on iOS, just in case if you had missed this, this is also mentioned in the documentation.

Hope that helped!

Here are some good resources if you’re getting started:

Spread the love! Cheers! 😀

XFHACKS-009 Frame with Border Image!

Ever wanted to have a Xamarin.Forms.Frame with a Border Image? Or have a Border Image around any of your Xamarin.Forms Elements? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

The Xamarin.Forms.Frame by default only has a boring BorderColor property without even letting you to set the Width of the Border or even set an Image as the Border.

So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol! A Frame with a Border Image property along with the Border Width! 😉

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 I’ve been writing quite a few hacks around Xamarin.Forms Frame element, and this recipe is also going to be based on my previous posts, XFHACKS-007 Frame with a Border Width! I would rather recommend you read up on that before continuing here, regardless I would explain the same concept in short here as well. Basically we’re placing a Frame element (child) inside another Frame element (parent) with a Margin value which will create visually a single frame with a Border as our choice of the Margin.

Now keeping that in mind for our Border Image we’re simply going to add Grid into the parent Frame and place an Image in it, while using the IsClippedToBounds=”True” property in both parent Frame and Grid Layout to avoid the Image element rendering itself outside the bounds of the parent Frame. Then on top of that Image inside the same Grid we’re placing our child Frame that I mentioned before with the Margin property that renders the Border aspect of the whole view.

Just like that you get the entire custom element put together which you could use as a single Frame element with a Border Image! 😉

Code!

Behold the golden XAML code!

<!--  Frame with Border Image  -->
<Frame
    Padding="0"
    CornerRadius="7"
    HasShadow="False"
    IsClippedToBounds="True">
    <Grid HeightRequest="50" IsClippedToBounds="True">
        <Image Aspect="AspectFill" 
            Source="{extensions:ImageResource   
            XFHacks.Resources.abstractbackground1.jpg}" />
        <Frame
            Margin="5"
            Padding="0"
            BackgroundColor="White"
            CornerRadius="5"
            HasShadow="False"
            IsClippedToBounds="True">
            <!--
                Whatever the content you want to
                place inside the Frame goes in here
            -->
        </Frame>
    </Grid>
</Frame>

 

There you have the Frame with Border Image in XAML just like I explained earlier. We have the parent Frame with IsClippedToBounds and CornerRadius property, the Grid and the Image with form the Border Image. Notice the Padding=”0″, since we want the Image with the Grid to spread across the parent Frame. You could change the CornerRadius as you wish to control the curved corner of the Frame.

I have given a HeightRequest value to the Grid just to make sure it renders to the exact size I need, or you could even let the whole element freely size itself according to the Element inside the whole custom Frame.  Then on top of that we have the child Frame with the Margin property cropping our the center of the Image element that’s placed under it, thus forming the Border Image as we wanted! 😀

Now let’s put it together and build something awesome! 😀

Fire it up!

Let me showcase the awesomeness of this with something fun!

 

There you go! 😀 Running side by side Android, iOS and UWP.

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-008 Label with Border and Background!

Ever wanted to have a Xamarin.Forms.Label, with a Border, or even better with a Background, or with a Corner Radius customization? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

By default Xamarin.Forms.Label doesn’t have a Border, Background neither a Corner Radius property, the only possible way to achieve that is by resorting to custom renderers. So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

A Label with a Border and a Background, none other than with Corner Radius customization, a true dream come true for Xamarin.Forms developers! lol kidding! 😉

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 Now this hack basically has mostly to do with my previous post, XFHACKS-007 Frame with a Border Width! If you would like to read more on detail about it then please check that article and come back here, but let me explain it in short form here though. Basically we’re placing a Frame element inside another Frame element with a Margin value which will create visually a single frame with a Border as our choice of the Margin.

Now for our Label, we’re going to place it inside that custom Frame we just built, giving it a nicely rendered border around it. You have the complete control over the Border Width property as explained in my previous article.

And the best part of it is that this Frame will resize itself according to the Label inside of it, since we’re not restricting it to any static values, whatever the Height or Width property you set to the Label, the border will follow it. Talking of Alignment of the Label you can freely use the Margin, HorizontalOptions and VerticalOptions to easily align the Label inside the Border. 😉

Code!

Behold the golden XAML code!

<!--  Label with a Border  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="2"
        Padding="5"
        BackgroundColor="White"
        CornerRadius="5"
        HasShadow="False">
        <Label
            BackgroundColor="Transparent"
            HorizontalOptions="Center"
            Text="Border with curved corners"
            TextColor="Black" />
    </Frame>
</Frame>

 

There you have the Label with a Border in XAML! Just like I explained above the two Frames rendering the Border around it. Feel free to change the Margin value of the child Frame element to increase or decrease the Border-Width. And both Frames CornerRadius are used to give a curved corners effect to the Border. Let’s see it in actions:

If you want to have curved sides for the Label Border, then simply increase the CornerRadius=”16″ parent Frame and CornerRadius=”14″ for the child Frame.

Now Imagine if you want to Align the Label inside the Border, then simply use the HorizontalOptions property as you wish, for example HorizontalOptions=”Start” and just to avoid the Label crashing with the border use the Margin property of the Label in whichever the direction you’re aligning your Label to, as an example Margin=”5,0,0,0″

How about that Background I promised earlier, well then simply set the child Frame’s background Color as you wish, and if you prefer to have a different Color for Border and Background, just make sure to set different colors to parent Frame’s Background color and child Frame’s background color.

Now how about having a Background Image, what you need to do is simply add an Image behind the Label using a Grid Layout by laying down both the elements on top of each other.

<!--  Label with a Background  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="2"
        Padding="0"
        BackgroundColor="White"
        CornerRadius="5"
        IsClippedToBounds="True"
        HasShadow="False">
        <Grid HeightRequest="30" IsClippedToBounds="True">
            <Image Aspect="AspectFill" Source="{extensions:ImageResource XFHacks.Resources.abstractbackground.jpg}" />
            <Label
                BackgroundColor="Transparent"
                FontAttributes="Bold"
                HorizontalOptions="Center"
                Text="With a Cool Background!"
                TextColor="White"
                VerticalOptions="Center" />
        </Grid>
    </Frame>
</Frame>

 

There you have it, the golden XAML! So what we have done here is basically the same concept but with a bit more icing on top, by removing the padding inside the child Frame allowing the Image background to stretch to on to the edge of the border. Then inside the child Frame we have a Grid Layout, and its got a HeightRequest property which determines the Height of the Label, meanwhile cropping out using IsClippedToBounds property, the excessive rendering of the Image inside that’s acting as the Background.

Now let’s put it together and fire it up! 😉

Fire it up!

Load your cannons, fire it up!

 

There you go! 😀 Running side by side Android, iOS and UWP.

A little Trick! 😉

Just like how I’ve implemented the Border and Background for the Label element, you could follow the same pattern and use this for any UI Element in Xamarin.Forms as you wish, such as Image, Editor, Slider, ListView, etc whichever you wish! 😉 Just replace that Label with the UI element of your choice! 😀

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-007 Frame with a Border Width!

Ever wanted to have a Xamarin.Forms.Frame with a Border which you can customize the Border-Width property? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

The Xamarin.Forms.Frame control is such a nice and useful UI element. One of the nicest features of it is the Border property, that draws a border around the View. But by default Xamarin.Forms doesn’t allow you to customize it, except for the BorderColor property, it is missing a very much needed property that even I personally wish if it had, that is the “Border Widthproperty, so that we can renderer a nice Border around the Frame as whatever the thickness we wish.

So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol! A Frame control with a Border Width property!

XFHACKS Recipe!

Buckle up fellas, its recipe time! 😉 So the idea here is to simply, build a custom control by adding a Frame Element inside of another Frame Element, like a View parent-child relationship, and giving some Margin property values to the child Frame, which creates a border-like visual around the child Frame, by the parent Frame. Here we can set the background color of the parent Frame as we wish, which will be rendered as the Border around the Frame, and the Margin property of the child Frame will determine the Width of the visible Border. So obviously since we need to push the child’s Frame throughout the panel of parent’s we’re setting the parent Frame’s Padding to zero. Then whatever the CornerRadius we want to set for our custom Frame will always be in a manner that the child Frame’s CornerRadius will be two points less than the parent Frame’s CornerRadius, this is to maintain the nice curved corner radius of the whole custom Frame once the border is rendered.

Also if you need to maintain the HasShadow feature for our custom Frame then you should only set it for the parent Frame, not the child Frame, and since we’re using our own custom built Border we are not going to be using the default BorderColor property of any of the Frames.

Code!

Behold the golden XAML code!

<!--  Frame with a Border Width  -->
<Frame
    Padding="0"
    BackgroundColor="#2196F3"
    CornerRadius="7"
    HasShadow="False">
    <Frame
        Margin="1"
        BackgroundColor="White"
        CornerRadius="5"
        HasShadow="False">
        <!--
            Whatever the content you want to
            place inside the Frame goes in here
        -->
    </Frame>
</Frame>

There we go, just like I explained the parent and child Frame positioned accordingly with the appropriate properties. Notice how I have set the Margin=”1″, which determines the Border Thickness or the Border Width, like I explained before.

Now you are ready to use our custom Frame with Border-Width just like you would as another Frame in Xamarin.Forms! Just place whatever the content you want to put inside the custom frame inside that child Frame as commented in the code snippet! 😉

Now let’s build something fun and fire it up! 😉

Fire it up!

Let me showcase the awesomeness of this with something fun, by comparing it with a default Xamarin.Forms Frame, and the coolness of being able to customize the Border-Width of a Frame! 😉

There you go, completely identical to the default Frame but packed with awesomeness!

Alright load your canons, fire it up!

   

Alright there you have it running on Android, iOS and UWP side by side! 😀

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Advanced Segmented Button Control in pure Xamarin.Forms!

Welcome to the Part 2 of my Segmented Button Control in Xamarin.Forms, in which this time we’re going to take it to the advanced level and make it even cooler and more awesome!

If you missed the Part 1 of this article, please go on there and give it a read,A Segmented Button Control in pure Xamarin.Forms! Specially since this article is going to be heavily linked to it. So there we looked into how to create a simple yet awesome Segmeneted Control in pure Xamarin.Forms without any custom renderers or native code. And in this article we’ll be looking into how to make it even more awesome with a bit more advanced implementation. Keep in mind I’m not going to explain all the concept bits which I had discussed in the Part 1 but I will be mentioning about them to be referred to. So let’s begin!

Welcome to Part 2!

A Segmented Control, or as some call it Grouped Button Control, or Tabbed Button Control or some even call the Rocker Control, is what I’m gonna share with yol today, built 100% from Xamarin.Forms! Specially in this Part 2 article, we’re including the ability to add Segmented Buttons on the go and change the Color themes at run time, making it full dynamic.

We’re going to rely on the same basic concept’s we talked about in Part 1 article, only the implementation and handling of the behavior to include the new features are going to be different in this.

Sneak Peak

Here’s a sneak peak of what I built for Part 2 article…

iOS:

  

Android:

   

that’s what we gonna build yo! 😉

FULLY DYNAMIC | ADDING/REMOVE TABS | SWITCHING COLORS  | SWITCHING TAB

Look at that awesomeness eh! Hold up, we’re about to get started…

This whole awesome project is hosted up in my Github repo:  https://github.com/UdaraAlwis/XFSegmentedControl 

Recipe time…

So this is basically going to be the same concepts we’ve used in the Part 1 therefore I’m not going to be repeating the same stuff I had explained in details in Part 1 Article. Please give a read to the “Recipe time…” section in it.

In here we’re going to separate the Tab Button element from the SegmentedControl, so that we can dynamically add the Tab Buttons dynamically at run time. We’re going to maintain an IEnumerable list in the SegmentedControl.

Also unlike last time we’re going to implement and properly handle the Color properties and SelectedTab index property, so that all those properties cab be changed dynamically as we wish.

Well that’s pretty much it, with a bit more details to be gotten into later.

Coding time…

So let’s begin with our separated TabButton element, which you could also identify as a “Segmented Button” element of our Segmented Button Control. This element includes with a simple Button, Label and BoxView inside of a Grid view, that makes it up just like the last article implementation.

<?xml version="1.0" encoding="UTF-8" ?>
<Grid
   x:Class="XFSegmentedControl.Advanced.Controls.TabButton"
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   IsClippedToBounds="True">
   <Button
      x:Name="TabButtonView"
      Margin="-2,-3,-2,0"
      Clicked="TabButton_OnClicked" />
   <Label
      x:Name="TabLabelView"
      FontAttributes="Bold"
      FontSize="Medium"
      HorizontalOptions="CenterAndExpand"
      InputTransparent="True"
      Text="Tab Text"
      VerticalOptions="CenterAndExpand" />
   <!--  Horizontal indicator for Android  -->
   <BoxView
      x:Name="HorizontalIndicator"
      HeightRequest="2"
      InputTransparent="True"
      IsVisible="False"
      VerticalOptions="End" />
   <!--  Vertical separator for iOS  -->
   <BoxView
      x:Name="VerticalSeparator"
      HorizontalOptions="Start"
      InputTransparent="True"
      IsVisible="False"
      VerticalOptions="FillAndExpand"
      WidthRequest="1" />
</Grid>

 

There’s the XAML with the basic Button and Label which handles the Text and click event of the TabButton and then the two BoxViews that we’re going to use to decorate for Android and iOS platform specific look and feel.

Check out the full source code here: TabButton.xaml

Next let’s take a look at the code behind awesomeness of our TabButton control.

public partial class TabButton : Grid
{
    public event EventHandler<EventArgs> TabButtonClicked;
    public string TabText { get; private set; }
    public int TabIndex { get; private set; }
    public Color PrimaryColor { get; private set; }
    public Color SecondaryColor { get; private set; }

    public TabButton(string tabText, int tabIndex, Color 
       primaryColor, Color secondaryColor, 
       bool isSelectedByDefault)
    {
        InitializeComponent ();

        // Set up default values from params
        ...
       
        // Set up default color values
        SetUpColorScheme();

        // set up selected status
        if (isSelectedByDefault)
            TabButtonView.SendClicked();
    }

    private void SetUpColorScheme()
    ...

    private void TabButton_OnClicked(
                  object sender, EventArgs e)
    {
        SetSelectedTabState();

        SendTabButtonClicked();
    }

    private void SetSelectedTabState()
    ...
    private void SetUnselectedTabState()
    ...

    /// <summary>
    /// Update the Tab Button status Selected/Unselected
    /// </summary>
    /// <param name="selectedTabIndex"></param>
    public void UpdateTabButtonState(int selectedTabIndex)
    {
        if (selectedTabIndex != TabIndex)
            SetUnselectedTabState();
        else
            SetSelectedTabState();
    }

    /// <summary>
    /// Update the Color status of the Tab Button
    /// </summary>
    /// <param name="primaryColor"></param>
    /// <param name="secondaryColor"></param>
    public void UpdateTabButtonColors(
           Color primaryColor, Color secondaryColor)
    ...
}

 

So in the code behind we’re handling all the functionality and look and feel appearance of the Tab Button segment or element. In the constructor itself we’re passing in the Color properties, Text, Index of the current Tab Button and the selected Status of this Tab Button, then we’re assigning them to the visual elements of the TabButton appropriately, whilst, storing the important values locally for later use.

The SetUpColorScheme() applies to color properties of the element, and I’ve moved that to a separate methods because we’re going to be allowing the user to update the color properties on the go. If you had noticed how we’re subscribing to the TabButton_OnClicked in our XAML code, there we’re handling it by calling the SetSelectedTabState() method and SendTabButtonClicked(), which will update the appearance of the current TabButton to the Selected State and then invoke the EventHandler for whichever the entity that’s subscribed to it from the outside.

Then the an important Public method, UpdateTabButtonState() which allows an external source to update the current Visual-Selected State of the TabButton. You can see how it calls upon the SetSelectedTabState() and SetUnselectedTabState() based on the passed in parameter selectedTabIndex.

Last but not least the UpdateTabButtonColors() allows us to update the Color theme of the TabButton on the go from an external source.

Check out the full source code here: TabButton.xaml.cs

Next we’re going to create the Parent custom control elements that’s going to be holding all of the TabButton elements together. Let’s call it AdvSegmentedControl, thus interpreting Advanced Segmented Control! 😉

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
   x:Class="XFSegmentedControl.Advanced.Controls.AdvSegmentedControl"
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:system="clr-namespace:System;assembly=netstandard">
   <ContentView.Content>
      <Frame
         x:Name="FrameView"
         Padding="0"
         IsClippedToBounds="True">
         <!--  Platform specific customization values for the border  -->
         <Frame.HasShadow>
            <OnPlatform x:TypeArguments="system:Boolean">
               <On Platform="Android" Value="False" />
               <On Platform="iOS" Value="True" />
            </OnPlatform>
         </Frame.HasShadow>
         <Frame.CornerRadius>
            <OnPlatform x:TypeArguments="system:Single">
               <On Platform="Android" Value="0" />
               <On Platform="iOS" Value="5" />
            </OnPlatform>
         </Frame.CornerRadius>
         <Frame.HeightRequest>
            <OnPlatform x:TypeArguments="system:Double">
               <On Platform="Android" Value="50" />
               <On Platform="iOS" Value="35" />
            </OnPlatform>
         </Frame.HeightRequest>
         <!--  Platform specific customization values for the border  -->

         <!--  Holder of the Child Tab buttons  -->
         <Grid x:Name="TabButtonHolder" ColumnSpacing="0" />

      </Frame>
   </ContentView.Content>
</ContentView>

 

That’s pretty much it, I’m sure you’re already familiar with the styling of the Frame element from my previous post and the Grid named as TabButtonHolder is what we’re going to be using in the code behind to maintain the Child elements of TabButtons.

Next comes the Code behind of AdvSegmentedControl 😀

public partial class AdvSegmentedControl : ContentView
{
   BindableProperty PrimaryColorProperty
   ...
   BindableProperty SecondaryColorProperty
   ...
   BindableProperty SelectedTabIndexProperty
   ...
   BindableProperty TabButtonsSourceProperty
   ...
   static void OnTabButtonsPropertyChanged
   (BindableObject bindable, object oldValue, object newValue)
   {
      if (newValue != null)
      {
         // clear up existing childrens
         ((AdvSegmentedControl)bindable)
                    .TabButtonHolder.Children?.Clear();

         int index = 0;
         foreach (var item in (IEnumerable) newValue)
         {
            // create new Tab Button
            var newTab = new TabButton(
            item.ToString(),
            index, 
            ((AdvSegmentedControl)bindable).PrimaryColor, 
            ((AdvSegmentedControl)bindable).SecondaryColor,
            (index == ((AdvSegmentedControl)bindable)
                                       .SelectedTabIndex));

            newTab.TabButtonClicked += (sender, args) =>
            {
               ((AdvSegmentedControl)bindable).SelectedTabIndex
                  = ((TabButton)sender).TabIndex;
            };
            
            Grid.SetColumn(newTab, index++);

            // add the new tab to TabButtonHolder
            ((AdvSegmentedControl)bindable).
                  TabButtonHolder.Children.Add(newTab);
         }
      }
      else
      {
         // clear up existing childrens
         ((AdvSegmentedControl)bindable).
                  TabButtonHolder.Children?.Clear();
      }
   }

   public AdvSegmentedControl ()
   ...
}

 

So its all similar to the previous article’s implementation, all the properties and handling of the behavior, except now we’re maintaining a list of TabButton references in TabButtonsSource property, which is a list of strings that we could use as names for the Tabs, instead of having a hard coded static Tab buttons in our previous implementation. And we’re subscribing to it to handle the adding and removal of the Tabs or Segmented Buttons at run time on demand.

Inside the loop we’re creating new instances of TabButton and passing in the relevant properties that are assigned, then subscribing to the TabButtonClicked event, ending each loop cycle by adding the TabButton instance to the TabButtonHolder Grid.

Check out the full source code here: AdvSegmentedControl.xaml.cs

Now that’s pretty much it. Let’s consume this awesomeness of AdvSegmentedControl! 😉

Time for consumption…

Now that we are done with our awesome AdvSegmentedControl, next let’s consume it in anywhere we wish in our Xamarin.Forms app!

<controls:AdvSegmentedControl
    x:Name="segmentedControl"
    PrimaryColor="CornflowerBlue"
    SecondaryColor="White"
    SelectedTabIndex="2"       
    SelectedTabIndexChanged="OnSelectedTabIndexChanged">
    <controls:AdvSegmentedControl.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="Android" Value="0" />
            <On Platform="iOS" Value="10,0,10,10" />
        </OnPlatform>
    </controls:AdvSegmentedControl.Padding>
    <controls:AdvSegmentedControl.TabButtonsSource>
        <x:Array Type="{x:Type x:String}">
            <x:String>Monkeys</x:String>
            <x:String>Minions</x:String>
            <x:String>Penguins</x:String>
            <x:String>Foxes</x:String>
        </x:Array>
    </controls:AdvSegmentedControl.TabButtonsSource>
</controls:AdvSegmentedControl>

 

There you go a simple demonstration of how to consume this awesomeness! We’re using PrimaryColor, SecondaryColor properties to set the color theme and the SelectedTabIndex property allowing you to set the default selected Tab on appearing. We have added a list of Strings to our TabButtonsSource to populate the Tab Buttons or Segmented Buttons as we wish. Also we’re subscribing to the SelectedTabIndexChanged event to react to the changes of the selected Tab by the user (you know load some view or execute whatever the action you wish). Keeping in mind all those properties can be changed at run time and will reflect visually! how awesome is that! 😀

Let’s fire it up and see it in action! 😉

Fire it up!

Here we go…

  

There we go baby! iOS and Android running side by side…

Something more awesome…

So just to show how powerful my AdvSegmentedControl is, I cooked up bit of a cool demo right here. Oh I hope you still remember that little sneak peak I showed you at the beginning of the article! 😉

Let’s start off with iOS:

 

And Android:

 

TADAAA! 😀

FULLY DYNAMIC | ADDING/REMOVE TABS | SWITCHING COLORS  | SWITCHING TAB

Check out the awesome demo code went into this from here: MoreDemoPage.xaml

Well your imagination is the limit fellas! 😀

This whole awesome project is hosted up in my Github repo:  https://github.com/UdaraAlwis/XFSegmentedControl 

Cheers! 😀 Keep on going my fellow devs!

Spread the love…

XFHACKS-006 Password Entry with show/hide Text feature!

Ever wished if your Xamarin.Forms Password Entry control had the option to reveal, or show the Password text that the User types on demand, instead of the black dots? 😉  Even better, without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

So in Xamarin.Forms to enable this feature usually you need to resort to creating Custom Renderers or some platform specific implementation, which is a tedious process and a complicated implementation. So I thought of making use of my own crazy imagination and hack my way around to get this to work right from Xamarin.Forms itself!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

Let the recipe begin! So basically the idea here is to have two Entry elements which represents the Entry with IsPassword enabled and another Entry with IsPassword disabled, laid on top of each other inside a Grid layout. Also we’re going to switch the visibility of these two Entry controls on a Button click event which will also be laid on top of both the Entry elements, aligned to the right most corner of the whole Grid layout. Just to add some cheery to the icing, let’s have a Button with an Icon Image inside of it, which implementation I’ll be extracting from one of my previous XFHACKS articles, XFHACKS-005 Button with full control on Text and Icon! ! Give it a read if you’re curious! 😉

Since we’re maintaining two Entry elements, we need to make sure both of them have the same Text value at any point of the user’s interaction. So to make this happen we’re going use Element to Element binding in Xamarin.Forms, where as we are binding the Text field properties of both Entry controls to eachother. Thereby one Entry’s Text changes immediately reflects on the other one and so on.

Just to show some love for my architectural practices, I’m going to move the whole Button click event and the handling of the behavior logic of this control into a TriggerAction, aha! separation of concern or loosely coupled and no direct code behind dependency allowing for more re-usability! 😀

Code!

Behold the golden XAML code!

<Grid
   Grid.Row="1"
   Grid.Column="0"
   HeightRequest="45"
   HorizontalOptions="FillAndExpand"
   IsClippedToBounds="True">

   <!--  Entry Password  -->
   <Entry
      x:Name="EntryPassword"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="True"
      IsVisible="True"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryText}, Path=Text, Mode=TwoWay}" />

   <!--  Entry Text  -->
   <Entry
      x:Name="EntryText"
      Grid.Row="0"
      Grid.Column="0"
      FontSize="Medium"
      IsPassword="False"
      IsVisible="False"
      Keyboard="Plain"
      Placeholder="Password"
      Text="{Binding Source={x:Reference EntryPassword}, Path=Text, Mode=TwoWay}" />

   <!--  Button with Icon  -->
   <Grid
      Grid.Row="0"
      Grid.Column="0"
      Padding="0,0,3,0"
      HeightRequest="27"
      HorizontalOptions="End"
      IsClippedToBounds="True"
      VerticalOptions="Center"
      WidthRequest="35">

      <!--  Button Control  -->
      <Button x:Name="ShowPasswordButton" BackgroundColor="White">
         <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
               <On Platform="Android" Value="-4,-6,-4,-6" />
               <On Platform="iOS" Value="0" />
            </OnPlatform>
         </Button.Margin>
         <Button.Triggers>
            <EventTrigger Event="Clicked">
               <triggers:ShowPasswordTriggerAction
                  EntryPasswordName="EntryPassword"
                  EntryTextName="EntryText"
                  IconImageName="ShowPasswordButtonIcon" />
            </EventTrigger>
         </Button.Triggers>
      </Button>

      <!--  Icon Image  -->
      <Image
         x:Name="ShowPasswordButtonIcon"
         HeightRequest="25"
         HorizontalOptions="Fill"
         InputTransparent="True"
         Source="{extensions:ImageResource XFHacks.Resources.showpasswordicon.png}"
         VerticalOptions="Fill"
         WidthRequest="25" />
   </Grid>

</Grid>

 

Here we go, explanation time! So the two Entry elements are laying on top of each other and bound to each other’s Text properties, while having one Entry as IsPassword=true and the other opposite. I have given names for the Elements because we need references of them to handle the behaviour inside our TriggerAction which I will show next.

Then the Button with the Icon Image Element is aligned to the very right corner of Parent layout, laying on top of both Entry elements. I have added some padding to it to avoid it conflicting with the border of the Entry in iOS and UWP, then for Android it shouldn’t really matter visually. There’s a HeightRequest=”27″ and WidthRequest=”35″ given to this Element group because I needed to have some horizontal space besides the Image icon visually. For the Image we’re using a EmbeddedResource type image, which makes things really easy for managing the Images.

Then for the Parent Grid Layout that holds all of these Elements together,is using IsClippedToBounds property to make sure everything holds inside the Bounds of the Grid as a single UI Element.

This is the most crucial part where inside the Button click event we’re invoking a TrigerAction called ShowPasswordTriggerAction which handles all the logic and behaviour of this custom control. And we’re passing in the names of the Elements we have assigned, into the Trigger so that we can look it up inside the TriggerAction, retrieve their runtime references and handle the behavior as we need. Pretty straightforward implementation there 😉

Next let’s look into the golden TriggerAction!

/// <summary>
/// The Trigger Action that will handle
/// the Show/Hide Passeword text
/// </summary>
public class ShowPasswordTriggerAction : TriggerAction<Button>
{
    public string IconImageName { get; set; }

    public string EntryPasswordName { get; set; }

    public string EntryTextName { get; set; }

    protected override void Invoke(Button sender)
    {
        // get the runtime references 
        // for our Elements from our custom control
        var imageIconView = ((Grid) sender.Parent)
                  .FindByName<Image>(IconImageName);
        var entryPasswordView = ((Grid) ((Grid) sender.Parent).Parent).FindByName<Entry>(EntryPasswordName);
        var entryTextView = ((Grid)((Grid)sender.Parent).Parent).FindByName<Entry>(EntryTextName);

        // Switch visibility of Password 
        // Entry field and Text Entry fields
        entryPasswordView.IsVisible =     
                       !entryPasswordView.IsVisible;
        entryTextView.IsVisible = 
                       !entryTextView.IsVisible;

        // update the Show/Hide button Icon states 
        if (entryPasswordView.IsVisible)
        {
            // Password is not Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.showpasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryPasswordView.Focus();
            entryPasswordView.Text = entryTextView.Text;
        }
        else
        {
            // Password is Visible state
            imageIconView.Source = ImageSource.FromResource(
                "XFHacks.Resources.hidepasswordicon.png",
                Assembly.GetExecutingAssembly());

            // Setting up Entry curser focus
            entryTextView.Focus();
            entryTextView.Text = entryPasswordView.Text;
        }
    }
}

 

Here’s the most important bit where we’re handling the behaviour logic of our awesome Password Entry Control! At the moment of Invoking the Button click we’re doing a simple FindByName<T> look up for our required Elements, that are the EntryPassword field, EntryText field, and the IconImage.

First of all we’re setting the visibility of the two Entry Elements opposite for each other, as in if the User clicks on Show Password state, then the Entry with Text property will be displayed, and the user clicks on Hide Password state then the Entry with Password property (black dots) will be displayed.

Then based on the state, we’re updating the button icon’s Image source, as you can see we’re setting the showpasswordicon.png and hidepasswordicon.png respectively depending on the current state.

Finally we’re doing something extra to make sure whatever the visible the Entry element is still on Focus after the switching of the Password visibility state.

There we go, pretty straight forward yeah!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

Alright let’s see this in action!

 

There you have it running on Android, iOS and UWP like a charm! 😀

NO CUSTOM RENDERERS! NO NATIVE CODE! MORE AWESOME! xD

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Improvement suggestion: I was discussing this with one of my colleagues and he pointed out an awesome tweak for a much better improvement, that is to use the same implementation with trigger and all but with a single Entry element with the IsPassword true and false state on demand instead of using two Entry elements. This is a great idea yet so simple, which will drastically improve the rendering performance. So if you wanna give it a crack please go ahead! And here’s a shout out to an awesome developer Akshay Kulkarni – ak47akshaykulkarnimake sure to check out his Github repo! 😉

XFHACKS-005 Button with full control on Text and Icon!

Ever came across an instance where you wished if you had more control or customization over the Text and Icon properties of your Xamarin.Forms Button? even better even without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Uh oh, in Xamarin.Forms?!

The default Xamarin.Forms Button has it’s own limitations for customisation, specially in the Text and Icon, there’s not much control over those properties in terms of,

  • Alignment of Text and Icon
  • Positioning of Text and Icon 
  • Default upper case Text in Android
  • Icon Image Size and Aspect Property
  • Icon Source only limited for Local Images

Talking of the Icon Source, you can only use Platform Specific Local Images for it, you cannot use Embedded Resources for it.

So I thought of making use of my own crazy imagination and hack my way around to fix all those limitations!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Usual approach…

Now as an out of the box solution for this we could avoid using Xamarin.Forms Button totally and switch to a Xamarin.Forms Label or Image control with a Tap gesture recognizer attached to it. But then it wouldn’t actually give that nice look and feel of a button does it, specially in Android that nice ripple effects and on iOS the fade out effect on the button click is something really nice to have on your UI.

So… wait for it….

XFHACKS Receipe!

Here’s my awesome solution, we’re still going to stick to Xamarin.Forms Button button, and we’ll be laying down a Label or an Image on top of our Button view inside a Grid layout. This is actually very common hack of mine if you had gone through previous XFHACKS articles of my blog.

Yep sounds super simple, yet solves all of the issues I just mentioned above. Basically we’re constructing our own Custom Button control right from Xamarin.Forms elements, properties and behaviours without any custom renderers or platform code.

So getting into more details, here’s how we’re going to solve the above talked issues. For Alignment of the Text and Icon in the button, we are going to use the HorizontalOption of both Image and Label element that we’re placing on top of the Button. Then the Position of those elements, we shall resort to the Margin property of each. Since we’re using the Image control itself the Source property issue is automatically solved. Then as an added advantage you could also have the control over the Aspect property of the Image Icon you want to display in your button.

Now on top of all that one might wonder when you place a Label or Image on top of a Button, wouldn’t it obstruct the Clickable touch area of the Button? That’s where InputTransparent comes into rescue, passing down the touch even down to the Button straight away!

To add some cherry on top of the icing, we’re going to use the IsClippedToBounds property to crop out any areas of the inner elements of the Grid being rendered outside the View bounds of the Grid itself, so everything comes together as a single Element on UI.

Now all these comes together solving the issues that I have pointed out at the beginning! 😉

Sneak Peak!

That’s what we gonna be build yol!

Code and Run!

Behold the golden XAML code!

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="1"
    Grid.Column="0"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Margin="10,0,0,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="Start"
        HorizontalTextAlignment="Center"
        InputTransparent="True"
        Text="go next"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Margin="0,0,5,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.rightarrowicon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />
</Grid>

 

There you have it as we discussed earlier, our empty Button and on top of that the Label and the Image elements inside a Grid. As you can see the Button has some Margin value added for Android run time of, “-4,-6,-4,-5” which is to get rid of the default empty space that’s rendered around the Button at Android run time. The button will be spread across the whole Grid in background with its default HorizontalOptions=”Fill” property.

The Grid’s IsClippedToBounds=”True” property value makes sure it will cut off any inner elements that will render themselves out of the bounds of Grid. You can set whatever the HeightRequest or WidthRequest as you wish if you want to customize this even further.

Now speaking of the Label and Image you can see how I’m using the advantage of HorizontalOptions to align the elements as whatever the way I wish along with the Margin property of them, adding space wherever I wish. In here we have pushed the Label to the beginning of the Button and the Icon to the End of the Button horizontally.

Next the  InputTransparent=”True” comes in solving the touch issue, which will pass the touch action down to the Button element when the user clicks on it, giving the exact effect of a Button. The use of Image element we can now set whatever the size we wish for our Icon inside the button and adjust its Aspect property and so on.

And let’s try something else as well! Lets have a Button which has its Text and Icons aligned to the Right most corner.

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="0"
    Grid.Column="1"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button Grid.ColumnSpan="2" BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Grid.Column="0"
        Margin="0,0,5,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="End"
        HorizontalTextAlignment="End"
        InputTransparent="True"
        Text="favs"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Grid.Column="1"
        Margin="0,0,10,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.staricon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
</Grid>

 

Here’s another example where I have pushed the Image Icon to the End of the Button and the Label to be following it horizontally.

You can follow the same implementation and have our Button’s Text and Icon aligned t other Left most corner.

Now just like that you can customize all the aspects of a Button using this hack I just shared, just set up the Label and Icon with whatever the properties and customization as you wish on top of a Button. That’s it!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

Let me share some examples I’ve built using this awesomeness!

There you go our awesome Custom Button control running on Android, as you can see with all the preserved Button click effect! 😀

 

Since its completely out of the box Xamarin.Forms, you can run it across all the native platforms and expect the same results! 😉

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Simple Segmented Button Control in pure Xamarin.Forms!

A Segmented Control, or as some call it Grouped Button Control, or Tabbed Button Control or some even call the Rocker Control, is what I’m gonna share with yol today, built 100% from Xamarin.Forms!

Yeah such a platform specific UI element, right out of Xamarin.Forms without a single line of native code, how’s that even? Well if you’ve been following my blog for a while, you know that I’m all about pushing them limits of any given platform and achieve the impossibru! 😉

Whut whut in Xamarin.Forms?

So there’s many different interpretations of this UI elements and also different use cases. Specifically you can see this in native Tabbed Page views in both Android and iOS. And in native platforms they actually have their own Segmented button controls, that allows you to have a set of buttons in a single segment, that allows you to have a selected state, which will let you perform a certain operation, change a value or load a certain View to another element.

So when it comes to Xamarin.Forms, there’s no out of the box UI element that provides this view, unless you use Xamarin.Forms TappedPage control, in which case is impractical if you’re not in need of a Tabbed Page, or worse case in a Content element area where you absolutely can’t use a Page element.

Le Solucioano!

So here’s my solution for this, a Segmented Control in pure Xamarin.Forms, that allows you to have the same exact look and feel and behavior of a native Segmented Control, or a Tabbed Button Control or a Rocker Control or whatever. Lol

Specially no custom renderers, no native code or whatever, just simple and pure Xamarin.Forms! 😉

Sneak Peak

Here’s a sneak peak of what I built, on iOS..

And on Android..

Look at the eh, just like a native control with all the looks and feels and behaviours…

This whole awesome project is hosted up in my Github repo : https://github.com/UdaraAlwis/XFSegmentedControl 

Recipe time…

Buckle up, contains a whole bunch of me hacking around pushing the limits of Xamarin.Forms to achieve some impossibru! 😉

So first thing, we need to keep in mind the aspect of having the same look and feel of a native Segmented control, in aspect of both Android and iOS, therefore we’re going to be using a lot of platform specific properties in XAML and code behind.

We are going to have two Buttons inside a Layout, to emulate the two segmented Buttons. The layout is going to be a Xamarin.Forms Frame, since it has the property CornerRadius, which is vital to gain the curved corners appearance for iOS, and Border property, which we can use to draw the border around the element for iOS. As of Android we can disregard both of those properties. Also don’t forget about the IsClippedToBounds property which all the Layout elements has in Xamarin.Forms, allowing you to crop out of bounds elements inside the layout, which will allow us to have that curved corners in iOS without the button borders popping out of it.

So you might say as of the Button we could use a Label or something and then use a Tap Gesture to handle the click event. Nope! I like the perfection of whatever I’m building! 😉 Therefore we’re going to use actual Xamarin.Forms Button control, now hold on…

Now speaking of the Buttons, we can’t use Buttons with text inside, since the default behaviour of a button restricts the visibility of Text inside it. Therefore we’re going to use a little hack I have always used, that is placing one element over another inside a Grid view. So we are going to use a Button without text inside of it, and then a Label on top of it that represents the Text of the Segmented Button. So you’re probably worries about the Button click behaviour since we’re laying out a Label on top of it, but hello don’t worry, that’s where InputTransparent comes into rescue, passing down the touch even down to the Button straight away! So on selection of the Button we shall do the necessary changes to show the IsSelected status.

We are going to assign name identifiers to our elements in this control to handle some of the code behind magic as well, in case you wondered when you see the code! 😀

Also not to mention that we’re going to maintain properties inside the custom control, like Colors, Text, Selected Button Index properties and also an EventHandler to inform the changes of the Segment button selection.

Well that’s pretty much it, with a bit more details to be gotten into later.

XAML time…

We’re going to create a custom control elements that’s going to be independent and reusable anywhere in the project. Let’s call it SimSegmentedControl, thus denoting “Simple Segmented Control”!

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="XFSegmentedControl.Simple.Controls.SimegmentedControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:system="clr-namespace:System;assembly=netstandard">
    <ContentView.Content>
	
	<!--  Rest of content goes here (Next code snippet) -->
	
    </ContentView.Content>
</ContentView>

 

Now let’s get into the inside elements of our SimSegmentedControl, which is basically the Frame Layout that I explained before.

<Frame
    x:Name="FrameView"
    Padding="0"
    IsClippedToBounds="True">
    <!--  Platform specific customization values for the border  -->
    <Frame.HasShadow>
        <OnPlatform x:TypeArguments="system:Boolean">
            <On Platform="Android" Value="False" />
            <On Platform="iOS" Value="True" />
        </OnPlatform>
    </Frame.HasShadow>
    <Frame.CornerRadius>
        <OnPlatform x:TypeArguments="system:Single">
            <On Platform="Android" Value="0" />
            <On Platform="iOS" Value="5" />
        </OnPlatform>
    </Frame.CornerRadius>
    <Frame.HeightRequest>
        <OnPlatform x:TypeArguments="system:Double">
            <On Platform="Android" Value="50" />
            <On Platform="iOS" Value="35" />
        </OnPlatform>
    </Frame.HeightRequest>
    <!--  Platform specific customization values for the border  -->

    
    <!--  Segmented Buttons go in here (Next code snippet)  -->
    
</Frame>

 

As you can see I have added a whole bunch of platform specific customization values for Android and iOS to achieve the design we’re targeting for, such as CornerRadius and Height.

Then let’s add our Segmented Button elements, just to make it easier let’s identify each of them as “Tab Button” element.

<Grid ColumnSpacing="0">

    <!--  Tab button 1  -->
    <Grid Grid.Column="0" IsClippedToBounds="True">
        <Button
            x:Name="Tab1ButtonView"
            Margin="-2,-3,-2,0"
            Clicked="Tab1Button_OnClicked" />
        <Label
            x:Name="Tab1LabelView"
            FontAttributes="Bold"
            FontSize="Medium"
            HorizontalOptions="CenterAndExpand"
            InputTransparent="True"
            Text="Tab 1"
            VerticalOptions="CenterAndExpand" />
        <BoxView
            x:Name="Tab1BoxView"
            HeightRequest="2"
            InputTransparent="True"
            IsVisible="False"
            VerticalOptions="End" />
    </Grid>
    <!--  Tab button 1  -->

    <!--  Tab button 2  -->
    <Grid Grid.Column="1" IsClippedToBounds="True">
        <Button
            x:Name="Tab2ButtonView"
            Margin="-2,-3,-2,0"
            Clicked="Tab2Button_OnClicked" />
        <Label
            x:Name="Tab2LabelView"
            FontAttributes="Bold"
            FontSize="Medium"
            HorizontalOptions="CenterAndExpand"
            InputTransparent="True"
            Text="Tab 2"
            VerticalOptions="CenterAndExpand" />
        <BoxView
            x:Name="Tab2BoxView"
            HeightRequest="2"
            InputTransparent="True"
            IsVisible="False"
            VerticalOptions="End" />
    </Grid>
    <!--  Tab button 2  -->

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

 

Voila! behold the two button elements, with all the platform specific customizations, just like how I explained before, Label on top of a Button inside a Grid layout. Also you may have noticed the Margin property that I have used with “-2,-3,-2,0”, which is to stretch out the empty border line of the buttons out of the Grid so it crops out with the IsClippedToBounds property.

And the BoxView is to emulate the bottom line we have in Android look and feel of the Segmented Control.

Code-behind time…

Now this is where we’re basically going to handle all the action in our SegmentedControl!

So I’m not going to spoon feed the whole code in this blog post, since its going to be a pretty lengthy one, so I’ll be cutting out most of the repetitive code which you can easily figure out yourself or just check out on my github repo where I have committed this whole project code.

So like I explained at beginning we’re going to have a bunch of properties that are going to handle all the customization values such as Color, Text, SelectedIndex, EventHandler and so on. And then apply a whole bunch of code behind customization for platform specific look and feels, along with the handling of Segment button click event behavior.

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SimSegmentedControl : ContentView
{
    public static readonly BindableProperty PrimaryColorProperty
        = BindableProperty.Create(
            nameof(PrimaryColor),
            typeof(Color),
            typeof(SimSegmentedControl),
            Color.CornflowerBlue);

    public Color PrimaryColor
    {
        get { return (Color)GetValue(PrimaryColorProperty); }
        set { SetValue(PrimaryColorProperty, value); }
    }

    // SecondaryColorProperty

    // Tab1TextProperty

    // Tab2TextProperty

    // SelectedTabIndexProperty
    
    public event EventHandler<SelectedTabIndexEventArgs> SelectedTabIndexChanged;

    public SimSegmentedControl()
    {
        InitializeComponent();
    }

    /// <summary>
    /// load up the customizations and applying
    /// properties when the element has rendered
    /// </summary>
    protected override void OnParentSet()
    {
        base.OnParentSet();
        
        // Setting up platform specific properties for Android and iOS
        if (Device.RuntimePlatform == Device.Android)
        {
            Tab1LabelView.FontSize
                = Device.GetNamedSize(NamedSize.Medium, Tab1LabelView);
            Tab2LabelView.FontSize
                = Device.GetNamedSize(NamedSize.Medium, Tab1LabelView);

            Tab1ButtonView.BackgroundColor = PrimaryColor;
            Tab2ButtonView.BackgroundColor = PrimaryColor;

            Tab1BoxView.Color =
            Tab2BoxView.Color =
            Tab1LabelView.TextColor =
            Tab2LabelView.TextColor = SecondaryColor;
        }
        else if (Device.RuntimePlatform == Device.iOS)
        {
            Tab1LabelView.FontSize
                = Device.GetNamedSize(NamedSize.Small, Tab1LabelView);
            Tab2LabelView.FontSize
                = Device.GetNamedSize(NamedSize.Small, Tab1LabelView);

            Tab1ButtonView.BackgroundColor =
            Tab2ButtonView.BackgroundColor = PrimaryColor;

            FrameView.BorderColor =
            Tab1LabelView.TextColor =
            Tab2LabelView.TextColor = SecondaryColor;
        }

        Tab1LabelView.Text = Tab1Text;
        Tab2LabelView.Text = Tab2Text;

        // setting up default values
        SelectTab1();
        SelectedTabIndex = 1;
        SendSelectedTabIndexChangedEvent();
    }

    private void Tab1Button_OnClicked(object sender, EventArgs e)
    {
        SelectTab1();
        SelectedTabIndex = 1;
        SendSelectedTabIndexChangedEvent();
    }

    private void Tab2Button_OnClicked(object sender, EventArgs e)
    {
        SelectTab2();
        SelectedTabIndex = 2;
        SendSelectedTabIndexChangedEvent();
    }
    
    // SelectTab1()
    
    // SelectTab2()
    
    // SendSelectedTabIndexChangedEvent()
}

 

So we PrimaryColor and SecondaryColor which handles the two main colors that is styling our SimSegmentedControl, which is exactly how it being used in native version of this control as well, just two simple Colors styling the whole element.

Then Tab1Text and Tab2Text property to handle the Text that needs to be displayed in the Segmented buttons.

As you can see OnParentSet (this is when the View is rendered in memory and just about to be displayed on the Page) we’re applying all the platform specific customization for the elements in our SimSegmentedControl. Then you can see we’re setting the Tab1 and Tab2 text properties to our Labels, which is not actually good practice, but I was too lazy to add that in the PropertyChangedEvent handler of those respective bindable properties. After that at the end you can see we’re setting the default values.

Also the SelectedTabIndexChanged EventHandler is there to notify any outside element who wants to be aware of the selected Tab in our SimSegmentedControl, so they can perform whatever the action based on it.

Then let me get into the SelectTab1(), SelectTab2() and SendSelectedTabIndexChangedEvent methods.

private void SelectTab1()
{
    // set up platform specific
    // properties for SelectTab1 event
    if (Device.RuntimePlatform == Device.Android)
    {
        Tab1BoxView.IsVisible = true;
        Tab2BoxView.IsVisible = false;
    }
    else if (Device.RuntimePlatform == Device.iOS)
    {
        Tab1ButtonView.BackgroundColor = SecondaryColor;
        Tab2ButtonView.BackgroundColor = PrimaryColor;

        Tab1LabelView.TextColor = PrimaryColor;
        Tab2LabelView.TextColor = SecondaryColor;
    }
}

private void SelectTab2()
{
    // set up platform specific
    // properties for SelectTab2 event
    if (Device.RuntimePlatform == Device.Android)
    {
        Tab1BoxView.IsVisible = false;
        Tab2BoxView.IsVisible = true;
    }
    else if (Device.RuntimePlatform == Device.iOS)
    {
        Tab1ButtonView.BackgroundColor = PrimaryColor;
        Tab2ButtonView.BackgroundColor = SecondaryColor;

        Tab1LabelView.TextColor = SecondaryColor;
        Tab2LabelView.TextColor = PrimaryColor;
    }
}

/// <summary>
/// Invoke the SelectedTabIndexChanged event
/// for whoever has subscribed so they can
/// use it for any reative action
/// </summary>
private void SendSelectedTabIndexChangedEvent()
{
    var eventArgs = new SelectedTabIndexEventArgs();
    eventArgs.SelectedTabIndex = SelectedTabIndex;

    SelectedTabIndexChanged?.Invoke(this, eventArgs);
}

--------------

public class SelectedTabIndexEventArgs : EventArgs
{
    public int SelectedTabIndex { get; set; }
}

 

So there you can see in SelectTab1() we’re setting up the necessary customization for the Selected state of our Segmented Button for both Android and iOS, such as the BackgroundColor, TextColor and whatnot. And then in SelectTab2() we’re doing the exact opposite customization, Button 1 -> Unselected and Button 2 -> Selected appearance.

Then in the SendSelectedTabIndexChangedEvent we’re basically broadcasting the selected Tab index of our SimSegmentedControl with the SelectedTabIndex property value.

Time to consume!

Let’s use this awesome SimSegmentedControl in our Page shall we?!!! 😀

<local:SimSegmentedControl
	x:Name="SegmentedControlView"
	PrimaryColor="CornflowerBlue"
	SecondaryColor="White"
	SelectedTabIndexChanged="SegmentedControlView_SelectedTabIndexChanged"
	Tab1Text="Monkeys"
	Tab2Text="Minions">
	<local:SimSegmentedControl.Padding>
		<OnPlatform x:TypeArguments="Thickness">
			<On Platform="Android" Value="0" />
			<On Platform="iOS" Value="10,0,10,10" />
		</OnPlatform>
	</local:SimSegmentedControl.Padding>
</local:SimSegmentedControl>

 

Easy peasy, you just set the property values such as PriaryColor, SecondaryColor and so on that we created in our SimSegmentedControl and do a bit of customization if you wish to 😉 like I’ve added some padding for iOS!

In case if you’re wondering how to use the SelectedTabIndexChanged, you basically subscribe to that event and perform whatever the action you desire, whether it be changing some values, or swapping some Views or whatever your requirement is!

private void SegmentedControlView_SelectedTabIndexChanged
			(object sender, SelectedTabIndexEventArgs e)
{
	if (e.SelectedTabIndex == 1)
	{
		ContentView1.IsVisible = true;
		ContentView2.IsVisible = false;
	}
	else if (e.SelectedTabIndex == 2)
	{
		ContentView1.IsVisible = false;
		ContentView2.IsVisible = true;
	}
}

 

Just like that!

Let’s fire it up!

Let’s see this beauty in action now! 😀

Here we go baby! iOS and Android running side by side…

 

Let’s change up a bit of the colors shall we!

Woot, whatever the color combination you wish! 😉

Improvement suggestions..

Well if you ask me this is not the exact implementation I used for my actual requirement, this is more of a very simple implementation of it.

But there’s many ways to improve this. One would be adding Command for the selected Tab Index changed property handling. Also add both way handling of SelectedTabIndex so that we can set the default selected Tab on the go. Specially add dynamic Tab Buttons to the SimSegmentedControl at run time without just limiting to 2 buttons. 😉

Well your imagination is the limit fellas! 😀

This whole awesome project is hosted up in my Github repo : https://github.com/UdaraAlwis/XFSegmentedControl 

Check out the Part 2 of this article: Advanced Segmented Button Control in pure Xamarin.Forms!

Cheers! 😀 Keep on going my fellow devs!

Spread the love…