Sometimes the design of our apps requires us to create custom elements inside of Xamarin Forms.
One thing I wanted to try out, was using a floating tabbar instead of a bottom fixed one.

The end result should be this:

Let me show you how you can achieve this in Xamarin Forms targeting iOS.

We actually don’t want to create our own page panel switcher or view host, rather, we would love to reuse the current TabbedPage that is provided by Xamarin Forms. So if we want to alter the one given by Xamarin, we need to create a Custom Renderer for it.
In this custom renderer we will be hide the default TabBar that is provided by iOS and instead we will load a Xamarin Forms ContentView and place it inside the UIView that is currently loaded; placing it somewhere on the bottom of the page.

Now that our view is visible and the default tabbar is hidden, we only need to trigger the actual tab switching.
This is done inside our ContentView!
Inside of the new TabBar view, we have defined 3 buttons. Each button will trigger a page switch, doing this through use of the Xamarin Forms Tabbed Page. We just switch the CurrentPage property of the TabbedPage and this will trigger the normal tab switching.

Since a while we are able to render a bottom tabbar in Xamarin Forms for Android!
If you want to know the whole setup, take a look at this great blog post by James Montemagno here…

So recently we added this in our production app, because our own implementation was not always working 100% correct depending on the Android version it was being shown.

But we also needed some extra functionality and didn’t want to bring in an external library. So let me show you what we needed and how we added this to Xamarin Forms Android.

First extra needed feature was the ability to show tab badges. In other words a counter that shows, in our case, the amount of unread messages.
End result should be:

Now the fact that we eventually also need to port this to iOS, means we need some abstracted elements that reside in Xamarin Forms project and not in the os specific projects.
First we need a small class that can contain the badge info that we want to show, it has 2 properties, one for the badge caption and one for the badge color.

So when you want to dynamically change the color or caption, you just change the data in the properties and the code on os level will handle this.
Because we want to interact on os level, we need to create a Custom Renderer. To be sure it can get a hold of the TabData class we also create our own TabbedPage first.

C#

1

2

3

4

5

6

7

8

9

10

11

publicclassBottomTabbedPage:TabbedPage

{

publicboolLabels{get;set;}

publicDictionary<int,TabData>Tabs=newDictionary<int,TabData>();

publicBottomTabbedPage()

{

Tabs.Add(0,newTabData(){BadgeColor=Color.RoyalBlue,BadgeCaption=5});

}

}

I pre-init this page with a badge for the first tab that is blue and has 5 as caption.
With that in place we can start adding our Android Custom renderer.

The actual end goal of the custom renderer is to inject a badge control in each tab where needed. So we have to go through the Tabs dictionary of the BottomTabbedPage to see if we need to add a badge or not. Also we want to hook into the PropertyChanged event of the BadgeData class, so that we can actually change the visuals while the app is running.
This is all handled in the OnElementChanged method of the Custom Renderer.

A bunch of code, but it’s not that difficult to understand… first we adjust the Shift Mode so that our tabs are always shown equally ( reference the blog post of James on top ).
After that we go through the defined TabData elements and get the corresponding BottomNavigationItemView ( the actual item being rendered ).

Note that in my example, I only have a badge on the first tab. When you want badges on each, you need to pre init the TabData list for each tab.

When we want to add a badge, we create a new TextView element and add it to the corresponding BottomNavigationItemView. The TextView itself is just text but with a circular background element ShapeDrawable, that inherits the color you specified in the BadgeData.
All this code can be seen in the BadgeView class.

Also note that we keep track of the PropertyChanged event, so that we alter the color and caption if needed of the presented BadgeView.
And that’s it for our first feature! Bottom tabs with badges for Android.

But we also wanted to have the ability to show only icons on the tabs, so loosing the labels. This will of course only work when you have very descriptive icons.
This should look like so:

Now normally this should be very easy in Android API 28, because there you can provide a value stating if you want labels or not… but since of this writing Xamarin Forms is not yet 28 compatible ( https://github.com/xamarin/Xamarin.Forms/issues/3083 ) so we need our own implementation.

For this to work, we will strip out the labels that are available in the TabView. But that is not enough, we also need to shift down the icon. Because when you loose the labels, the icon will not be in the center of the TabView. On our BottomTabbedPage class we already added a bool property Labels that we can set in XAML to indicate if we want tabs with or without labels.

So we take the actual height of the tab itself, divided by 2 to get the center. Than we grab the height of the icon and also divide this by 2 and also get the current top position of the icon. With those values we now know how much pixels we need to add as top padding to our icon to get it vertically center.

All in all not that much code, but as always with android, you need to know how the actual objects are called and rendered.

Assume you have some news page that contains a header with the actual news title, some highlight image and a lot of body text.
If this is represented on a mobile device, depending on the screen resolution, this can result in the user needing to scroll the text content to be able to read everything.
Now if you just put the whole page in a ScrollView, the user will loose the content of the article he is reading, because most likely the title will also scroll out of view.
So let me show you what you can do to keep the title fixed as soon as it reaches a certain anchor point on screen, while the user is scrolling the text content.

The starting view looks like this

You will notice the title “Bear found in the wild” is fixed to the bottom of the highlight picture and as soon as the user scrolls, this will also scroll to the top of the screen. But we want to keep it in view when it reaches the top of the image ( it will be fixed below the “Fixed header demo page title ). even if the user keeps scrolling down after we reached our anchor point.

<Span Text="Never heard before, but a bear was found in the wild!"FontAttributes="Bold"FontSize="18"/>

<Span Text="&#10;&#10;Bears are mammals of the family Ursidae. Bears are classified as caniforms, or doglike carnivorans, with the pinnipeds being their closest living relatives. Although only eight species of bears are extant, they are widespread, appearing in a wide variety of habitats throughout the Northern Hemisphere and partially in the Southern Hemisphere. Bears are found on the continents of North America, Central America, South America, Europe, and Asia.

&#10;&#10;Common characteristics of modern bears include large bodies with stocky legs, long snouts, shaggy hair, plantigrade paws with five nonretractile claws, and short tails. While the polar bear is mostly carnivorous and the giant panda feeds almost entirely on bamboo, the remaining six species are omnivorous, with varied diets.

&#10;&#10;With the exceptions of courting individuals and mothers with their young, bears are typically solitary animals. They are generally diurnal, but may be active during the night (nocturnal) or twilight (crepuscular), particularly around humans. Bears are aided by an excellent sense of smell, and despite their heavy build and awkward gait, they can run quickly and are adept climbers and swimmers. In autumn, some bear species forage large amounts of fermented fruits, which affects their behaviour.[1] Bears use shelters, such as caves and burrows, as their dens; most species occupy their dens during the winter for a long period (up to 100 days) of sleep similar to hibernation.[2]

&#10;&#10;Bears have been hunted since prehistoric times for their meat and fur. With their tremendous physical presence and charisma, they play a prominent role in the arts, mythology, and other cultural aspects of various human societies. In modern times, the bears' existence has been pressured through the encroachment on their habitats and the illegal trade of bears and bear parts, including the Asian bile bear market. The IUCN lists six bear species as vulnerable or endangered, and even least concern species, such as the brown bear, are at risk of extirpation in certain countries. The poaching and international trade of these most threatened populations are prohibited, but still ongoing."

FontSize="14"/>

</FormattedString>

</Label.FormattedText>

</Label>

</Grid>

</ScrollView>

<Labelx:Name="TitleText"

Text="Bear found in the wild!"

TextColor="White"

BackgroundColor="#FF264778"

HeightRequest="40"

VerticalOptions="Start"VerticalTextAlignment="Center"

HorizontalTextAlignment="Center"/>

</Grid>

</Grid>

</ContentPage>

Import thing to note here, is that the actual TitleText label is positioned outside of the ScrollView! This is needed, because we will animate it ourselves depending on the scroll values of the ScrollView.
So how do we position this TitleText to the bottom of the bear image? This is done in the code behind of the page! In the constructor we hookup to the SizeChanged event of the bear image and in that event we will set the margin of the TitleText to the Height of the bear image minus the height of the TitleText itself.

1

2

3

4

5

6

7

8

9

BearImage.SizeChanged+=OnBearImageSizeChanged;

privatevoidOnBearImageSizeChanged(objectsender,System.EventArgse)

{

BearImage.SizeChanged-=OnBearImageSizeChanged;

//When the bear image has been loaded, reposition the news header to the bottom of this image

TitleText.Margin=newThickness(0,BearImage.Height-40,0,0);

}

Now when the TitleText has been fixed to it’s starting position, we need to take hold of the top Y coördinate. This is needed to calculate the anchor point while scrolling.
We also hookup to the SizeChanged event of the TitleText and when it changes, we can grab the Y point.

1

2

3

4

5

6

7

8

9

10

11

12

TitleText.SizeChanged+=OnTitleTextSizeChanged;

privatevoidOnTitleTextSizeChanged(objectsender,System.EventArgse)

{

TitleText.SizeChanged-=OnTitleTextSizeChanged;

//As soon as the news header has been repositioned, we can grab the actual screen top position

_titleTextTop=TitleText.Y;

//Remark: GetScreenCoordinates will get the actual position on screen instead of the actual position inside the parent

//_titleTextTop = GetScreenCoordinates(TitleText).Y;

}

Only one thing left to do, we now have to keep hold of the scroll values of the ScrollView, so we can animate the TitleText in sync with the scroll position and direction.
So we subscribe to the PropertyChanged event of the ScrollView and look for Y value changes.
When we get a change, we validate if it is still lower than our anchor point, if so, animate the TitleText Y coördinate to the same value. If it’s passed the anchor point, we will just keep the TitleText coördinate the same. This will result in the title being kept in view!

But what do you do when your custom font has no build in Bold feature and you have to rely on a separate custom font for that?
Well, you can let your XAML style check for a trigger and swap the font!
It’s fairly easy, so the code will now look like:

When UWP comes into play with Xamarin Forms, you’ll notice that several default control settings are often not resulting in a pleasing UI.

One that caught my eye recently was the way the height is set in a grouped lisview header.
So assume following setup, you define a listview and enable grouping. With that you would like to control what is being shown in the header, so you define your own GroupHeader Template. Inside the template, you only need a small display area, so for demo purpose we will only enable a Label control, but are setting it’s height to a fix amount of 25!
Complete XAML look like this:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<ListViewx:Name="ItemsListView"

ItemsSource="{Binding Items}"

VerticalOptions="FillAndExpand"

HasUnevenRows="true"

RefreshCommand="{Binding LoadItemsCommand}"

IsPullToRefreshEnabled="true"

IsRefreshing="{Binding IsBusy, Mode=OneWay}"

IsGroupingEnabled="True"

CachingStrategy="RecycleElement"

ItemSelected="OnItemSelected">

<ListView.GroupHeaderTemplate>

<DataTemplate>

<ViewCell Height="25">

<StackLayout HeightRequest="25"BackgroundColor="Lime">

<Label Text="HEADER"Margin="5,0,0,0"/>

</StackLayout>

</ViewCell>

</DataTemplate>

</ListView.GroupHeaderTemplate>

<ListView.ItemTemplate>

<DataTemplate>

<ViewCell>

<StackLayout Padding="5"BackgroundColor="Yellow">

<Label Text="{Binding Text}"

LineBreakMode="NoWrap"

Style="{DynamicResource ListItemTextStyle}"

FontSize="16"/>

<Label Text="{Binding Description}"

LineBreakMode="NoWrap"

Style="{DynamicResource ListItemDetailTextStyle}"

FontSize="13"/>

</StackLayout>

</ViewCell>

</DataTemplate>

</ListView.ItemTemplate>

</ListView>

When this is done you’ll get the following layout on iOS ( I added background colours to show off the different templates and their heights ).

So everything is looking ok in reference to what we defined in XAML, but now let’s look at UWP…

Well this is odd! Somehow the height of our headers is larger than what we defined… looks like UWP has some default rendering that overrides what we have set.
So after some digging through the source code of Xamarin forms, I’ve not found any special setting that could trigger this. In other words it’s not something Xamarin does to the UWP rendering of the listview.
This meant I needed to go look at the default template settings of the UWP control itself. What I found was that the listview control has a special header template style defined that uses a specific value for the minimum height for the ListViewHeaderItemMinHeight!
It’s set to 44… this explains our weird look and feel on UWP.

With this in mind it’s actually very easy to fix this in our app. All we need to do is provide a better minimum height value for the given style key.
When using UWP in Xamarin forms, you do this sort of overrides inside your App.xaml file by defining a theme resource dictionary and adding the same key like so:

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<Application

x:Class="App1.UWP.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="using:App1.UWP"

RequestedTheme="Light">

<Application.Resources>

<ResourceDictionary>

<ResourceDictionary.ThemeDictionaries>

<ResourceDictionaryx:Key="Default">

<x:Doublex:Key="ListViewHeaderItemMinHeight">1</x:Double>

</ResourceDictionary>

</ResourceDictionary.ThemeDictionaries>

</ResourceDictionary>

</Application.Resources>

</Application>

With this in place our UI will finally look like the same as the iOS counterpart.

We had to wait a while for it to happen, but it’s finally here; .Net Standard 2.0 support in Xamarin Forms.
This is a big step in sharing .net code across multiple platforms while able to target a wide range of APIs.

To show of the power of this, let’s do a fun example.
Wouldn’t it be nice if you could create Microsoft Office Excel of Word files on the fly inside your Xamarin Forms app? Of course you could offload this to a backend service, but that means you also need to be the owner of the data service. On the other hand creating simple CSV files that are compatible with Excel is also a possibility, but you are limited to only adding data in that case ( no formula’s or formatting ).

Thanks to .Net Standard 2.0 we can now use the full Office OpenXML SDK inside our Xamarin Forms apps!

First things first, how do we create a Xamarin Forms app with a .Net Standard 2.0 lib instead of a PCL.
To accomplish this now ( without any new Visual Studio templates ), just create a new blank PCL Xamarin Forms app.
When this is done, add an extra project but this time select a .Net Standard Library. You’ll get a popup window for selecting which version of .Net Standard you want to target, select Version 2.0!

When the project is inside your solution, first delete the class1 file and add the Xamarin Forms nuget package ( at least v 2.4.* ) and when that is done, just drag and drop the PCL files over to your new .Net Standard library.
Now you can just delete the old PCL project.
Reference the .Net Standard lib in your iOS and Droid projects and you are good to go.
For our example we also need to add the OpenXML nuget package so that we create and manipulate Docx and Xlsx files.

Let’s assume you have some data in a local database of pulled down from a REST service, it’s nicely presented on your screen and you can annotate and filter it.
When you are done you want to transfer this set over to some coworker but he is working in another environment and excel would suit better.

So how do we create an Excel file with this data blob?
Let me show you the code

I’ve created a separate method for inserting data into an existing Excel file ( in our case the one we just created with the code previously shown ).
This method uses a class called ExcelData it’s nothing more than a simple POCO with string lists… one for the headers and the rest for the data.

C#

1

2

3

4

5

publicclassExcelData

{

publicList<string>Headers{get;set;}=newList<string>();

publicList<List<string>>Values{get;set;}=newList<List<string>>();

}

Once the data is passed to the method, we’ll open up the first Worksheet available in our Excel file and inject data rows. Each row will get a set of Cells, in which we put our string data.
In this example I made it very straightforward and didn’t do any fancy Excel stuff… but now you have the basics of how to handle OpenXML files! If you go through the SDK docs, you’ll see that there is a lot more available.

Now that we have our filled up spreadsheet, we want to be able to share it. This can be done through platform specific code… for iOS we need to use a UIDocumentInteractionController

When this is used, you’ll be presented with an Open with popup where you can select different applications that are installed on your mobile device.
If Excel is installed you can actually see the generated file!

Back in the day there was this great open source lib called XLabs that targeted Xamarin Forms.
It had a lot of nifty controls and custom renderers to fix several pain points while developing for Xamarin Forms.
But Xamarin Forms evolved and XLabs was not maintained as regular anymore and it now seems to be stranded at a dead end.

BUT, even though the code targets an older version of Xamarin forms, it doesn’t mean that there is no longer any value in it.
I’ll give you an example: the RepeaterView.

This is a nice control that helps you ‘repeat’ data elements without actually using a ListView, this can be handy if you just want to show an iteration without any possible user interaction, or if you want to be able to show all items in the collection and control your own scroll region.

Whatever the reason, XLabs had us covered and we can still use it today!

So let me show you an example of how I needed to use it on a recent design issue I had.
I needed to present data grouped, but in 3 levels. Meaning, we have a bunch of payment transfers and they are grouped in ‘signed’ and ‘unsigned’ groups, but inside those main level groups we again need to group the transfers per user account. With each account listing the transfer items with their details…

In short, this would not be doable straight out of the box wit general ListView grouping. You could just put 2 ListViews on the page, but that would not help the UI. Because we want the user to be able to scroll through 1 list with all the data in it.

There are possibly several ways of fixing this, but I went for the use of RepeaterView in combination with a grouped ListView.

First let me show you what we are going to build ( don’t judge the layout 😉 )

Transaction and Account class, are the real data holders and we added GroupedTransaction and GroupedAccount to be able to actually group the data and use it for the grouped ListView.

Next up the RepeaterView, I modified the XLabs version so it would work in our newer Xamarin Forms environment, but do note that my version is also stripped down to the bare minimum that I needed for this UI.

The RepeaterView takes a generic T that is being used for the items enumerator. We need to keep that in mind when we write our XAML, because this has to be supplied there.
Other than that this control is very basic, you need to give it an ItemsSource and an ItemTemplate and it will use those to build the UI.
There is also an extra option to add a HeaderTemplate, if you want some text on top. But this isn’t used in this demo.

We are using a grouped ListView for creating the first and second data level, in our case the signed and unsigned transactions are mapped with the ListView GroupHeader, the account information is used in the ItemTemplate.
But also inside of the ItemTemplate we are using our RepeaterView to show the transactions.
This will give use 3 levels of information that are all repeatable.
Note the use of x:TypeArguments=”models:Transaction” on the RepeaterView, that’s the way to pass data to your model. This will be used for the type T of the RepeaterView.

When developing cross platform apps with Xamarin forms, you’ll notice that your apps will look and feel right at home on each OS. This because the nice people of Xamarin render each Xamarin forms control as a native control with the needed control properties all filled in.
You can still tweak some of these properties when they are leveraged through the Xamarin forms control abstraction or use custom renderers and effects to get down to the native control layer.

Most of the time this is all working great, but when you try to take UWP into account, you’ll notice not everything works straight out of the box.
Hence this blog post, showing you how you can hack the current TabbedPage implementation of Xamarin forms for UWP to enable pivot headers with images!

If you’ll use following XAML in Xamarin forms, you’ll get a nice Pivot control in UWP

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"

xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

xmlns:local="clr-namespace:TabbedPage"

x:Class="TabbedPage.MainPage">

<NavigationPage Title="Schedule 1"Icon="first.png">

<x:Arguments>

<local:SchedulePage/>

</x:Arguments>

</NavigationPage>

<NavigationPage Title="Schedule 2"Icon="second.png">

<x:Arguments>

<local:SchedulePage/>

</x:Arguments>

</NavigationPage>

</TabbedPage>

But when you run the app, you’ll notice that on UWP nothing is happening with the Icon property of the NavigationPage

While on iOS you’ll get something like this

So what gives? Well, the current Xamarin forms tabbed page implementation will not take into account this Icon property and ignore it during rendering.
Reading the guidelines from Microsoft, it’s recommended to actually do use icons for pivot headers if possible, read on it here https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/tabs-pivot.
The result should be something like this

Now let me show you a hack / workaround to get the same result on UWP. I stress hack, because of the current TabbedPage implementation in Xamarin forms there is no direct way to handle this.

To create a working solution, we need to change the HeaderTemplate that is specified inside that TabbedPageStyle. Normally we would just drop in a new Style with the same name inside our UWP App.Xaml file to override the one from Xamarin forms. But due to how Xamarin forms is initialised during startup this won’t work. So a small interception has to be made to get this going.

Add a new Styles.Xaml file in your UWP project and add following Style element to it

This will enable the use of the Icon property that we have set in our Xamarin forms xaml for each tab of the tabbedPage. Only thing left is swapping out the current HeaderTemplate and using ours.
So be sure to tell UWP we have this Style in our ResourceDictionary by adding it in the App.Xaml

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<Application

x:Class="TabbedPage.UWP.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="using:TabbedPage.UWP"

RequestedTheme="Light">

<Application.Resources>

<ResourceDictionary>

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="Styles.xaml"/>

</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>

</Application.Resources>

</Application>

After that, open up the App.Xaml.cs file and look for the Xamarin.Forms.Forms.Init(e); line.
Below it add an extra line of code to do the actual Template swapping

Like I said this is a hack… but it works perfectly 🙂 instead of using the default Xamarin forms TabbedPageStyle inside the Pivot header template we’ll now be using our own TabbedPageStyle2.
Only one small detail remains, you’ll notice I added a converter inside the Style. This was needed because the Icon property on the NavigationPage of Xamarin forms maps to a FileImageSource but that is not processable straight away as a source value for the Image control inside UWP.

The converter will get the File property of the FileImageSource and return that as a valid source. With this in place you’ll get the correct image shown!

Nothing all to special, we have a ListView hooked up with an ItemsSource and are using that together with an ItemTemplate to design the list items.
Because this is just a default implementation of a ListView we are seeing separators on iOS that are not full width.

To get a good separator we need to adjust our XAML!
First disable the default separator, this is done by adding following property to the ListView XAML

C#

1

SeparatorColor="Transparent"

After this, wrap the complete ViewCell content inside a double StackLayout! I know this sounds like overkill but this way you’ll not run into any BoxView issues regarding margins inside the ViewCell… or other stuff.
The first StackLayout should have a BackgroundColor set to the colour you want your separator to be, the second StackLayout should have the same BackgroundColor as the rest of the container it is in… in our example the page and that is set to white. Be sure to also add a Margin to the bottom of this second StackLayout because that will represent the thickness of our separator!

With that in place, you’ll get the same visual result as the preview image at the top right of this blog post.

As a bonus, you could omit one of the StackLayouts IF your page has a background color other than white. Because if this is the case, you can use that color as the separator color by playing with transparency inside the ListView.

Example of this, note will only work if the page itself also has a BackgroundColor set to Olive!

So, been seeing a lot of SVG support being introduced into UWP to get vector images. I love this evolution, but somehow I still love how fonts work and mostly I still go that route if I need some icon representation inside an UWP app.
Fonts also easily scale, by setting the font size, what often results in better outlining with text being set on the same size! Adding color is also no problem and depending on what library you are using there is often also a full filled version as an outlined version available for a given icon.

So let me show you this alternative way on how you can use a great open source icon library to good use inside your UWP apps, through their available font.

First up go to this great icon library called Material Design Icons, here select the Download button and in the popup window select the Download the webfont button. This will contain the materialdesignicons-webfont.ttf that we will use in our UWP app.
To use it in your app, place the TTF inside your Assets folder.

Now that you have the font as an asset, you’ll still need to enable its usage in xaml. To do this, we’ll first add a reference to the font in a ResourceDictionary.
Add following entry in your resource dictionary :

Now that the style is available for any TextBlock you want to use, we can add those in our UI.
For example if you want to add an expand symbol to an image to indicate the user can enlarge it, we just select a good icon from the font and place a TextBlock inside a button on the image.
Now the most difficult part is actually getting hold of the actual text representing a given icon.
To get this, you’ll need to install the TTF in windows ( right click on the font and select install ) and use the Windows Character Map tool to copy the value.

Select a given icon and press copy to get hold of the actual value

Only thing left to do is define an button and add a TextBlock to it with the font value.
Note : in the code preview below this will not be shown because the font value can not be rendered. But inside visual studio you will see a ? representation.