Xamarin forms – multi line label custom renderer gotcha

** UPDATE **

We expanded this and added an Effect for eveyone to use in the Xamarin Forms Community Toolkit!
It’s available here : https://github.com/FormsCommunityToolkit/FormsCommunityToolkit
The effect itself resides here : https://github.com/FormsCommunityToolkit/FormsCommunityToolkit/tree/dev/src/Effects/Effects/Label

On a project I’m working on, we needed a label that would show an ellipsis at the end. ( the 3 … indicating there is more text but not enough space on the screen to fit it all )

Having this on a label control in Xamarin forms is easy, you just add the property

this will force the ellipsis to appear if needed.

But on a specific page we wanted to show more text to the end user and even than add an ellipsis if needed. So in other words we would love to be able to tell the label control how many lines it should at least try to display.
To get this working in Xamarin forms you’ll need to add a custom renderer. Because the Xamarin forms label control doesn’t have any property available for us to manipulate to accomplish this.

This is not difficult at all to do, but there is a small gotcha with Android when you want to pull this off!

But let’s start with what you need to do to get this working.
In the Xamarin forms PCL ( so the general one, not the iOS or Android project ), we first add a class called MultiLineLabel.cs – this will be our own custom control.
It inherits from Label and we only need to add 1 dependency property called Lines, defined as an int. It looks like this:

After defining this custom control, we can use it on our XAML page, like so:

We will be using this Lines property in our custom renderers.
First up the iOS custom renderer for our MultiLineLabel. Create a class in the Xamarin forms iOS project called CustomMultiLineLabelRenderer.cs with following code:

You’ll notice that we are checking if the user specified a value for the Lines dependency property and if this is true, we pass this to the actual iOS UIKit.UILabel control by setting it’s Lines property. With this in place we get following result.

Screen Shot 2016-06-27 at 08.31.08

So iOS is done and looking great. Now add the Android renderer. Create a CustomMultiLineLabelRenderer.cs class in the Xamarin forms Android project with following code:

This doesn’t look all that different from the iOS counterpart… instead of setting a property we now use a method SetLines on the Android.Widget.TextView indicating how many lines we want it to display.
But wait, if we try this and look at the result, we’ll notice that it doesn’t work!!

Screen Shot 2016-06-27 at 08.31.05

It took me a while to figure this out ( I’m no Android expert 😉 ). But after taking a look in the Xamarin forms source code ( glad it’s open source 😉 ) I noticed they will always force a SetSingleLine(true) when setting the TailTruncation LineBreakMode…
Code can be seen here https://github.com/xamarin/Xamarin.Forms/blob/2d9288eee6e6f197364a64308183725e7bd561f9/Xamarin.Forms.Platform.Android/Renderers/LabelRenderer.cs#L179

So the fix is easy… you need to reset this Single Line forcing, the final code looks like this ( in your custom renderer ) :

With that in place we’ll get following result

Screen Shot 2016-06-27 at 08.31.31

Yeah success!
To start I’ve done a pull request on Xamarin forms to counter this SingleLine forcing, but not sure this will be added though… https://github.com/xamarin/Xamarin.Forms/pull/234
So better be safe and add the extra line in your own custom renderer for now.

As always example project up on github here…

UWP – Auto resizable flyout

So imaging you have this great looking layout in your UWP app, all set up with the new guidelines.
Meaning a side bar for navigation and a master detail section, that will dynamically change when you don’t have enough space to fit and master and detail.

We are talking about this layout:

Screenshot (37)

But of course like in most other apps, you want to enable some filtering on the content. That way the user can find the items that are more important to him… So for UWP there is a wonderful control that has all the needed qualities for such a feature; the MenuFlyout !
Now if you add this control, as is, it will only render itself in a certain width and height depending on the content that it contains. Meaning that most of the time, it will look tiny and out of place with the rest of the visual elements.
Here is a Phone screenshot example : notice how the flyout hovers above the side pane and it’s width is only calculated to it’s content

Wrong - 03 Mobile

What we would love to have, is a Flyout that takes up the full width size of the parent control it’s contained in… in other words in our example, have an equal width to the column that hosts the item list.
Let me show you how you can accomplish this.

First up, create this nice triple design, by using the new SplitView control, this will give you the side pane. Of course you’ll still need to add 2 columns to host the list and the detail content.
We’ll use the new Visual State Manager settings style to change the layout if we use the app on smaller screens!
Do note we are using a button with an empty button style to render the text for filter selection and a FlyoutMenu is attatched to that button. They are contained in the MasterColumn

Now that we have this all setup up, only thing left to do is calculate the actual width of the MasterColumn and use that to change the size of the flyout. But also take into account the side pane width to shit the flyout in place.
We will recalculate each time the flyout opens, because the app could be resized by the user before the flyout is actually opened.
So you’ll see a handler hooked up called for the Opened event called OnFilterFlyoutOpened with following code

The trick here is to change the MenuFlyoutPresenterStyle, with that style we can apply a minimum width to the actual flyout. That width should be equal to the width of the Master column…
We also apply some margin to compensate for the side pane.
By doing all this we now get following nice result :

Correct - 03 Mobile

As ever this sample can be found on my GitHub right here…

Xamarin forms – multi line page title

On a current Xamarin forms project I’m working on, there came the question if it would be possible to show 2 lines in the title bar of our app instead of 1.
Normally this is not something you would do, seeing the default behaviour on iOS and Android, an app would only display 1 line and cut if off by adding ‘…’.

But in our case we are showing detail information on a conversation and it would help the user if we could show some more context.

The goal would be like this:

Screen Shot 2016-05-30 at 22.04.41

Screen Shot 2016-05-30 at 22.05.27

To achieve this result, you’ll need to implement a custom renderer on each platform. Both on iOS and Android of the type PageRenderer.

First iOS.
In your Xamarin Forms solution, underneath the iOS project add a folder called CustomRenderers and add a class called CustomContentPageRenderer.cs.
Here we will implement a PageRenderer with following code

Inside the WillMoveToParentViewController method we will grab the current page and see if it does contain an actual Title ( not each page needs one ).
If so, we’ll new up an UILabel because with this iOS control we can set how many lines need to be used ( if needed ) : titleLabel.Lines = 2.
We must ofcourse not forget to pass the current page title to it and only thing left afterwards is placing this UILabel in the TitleView of the current navigation page : parent.NavigationItem.TitleView = titleLabel.

By doing this we will override the normal Xamarin Forms rendering of the title in a navigation page and allowing use of 2 lines in it!

Secondly Android.
Same setup as in iOS, so a CustomRenderers folder with a CustomContentPageRenderer class file. But there is a bit more code needed for this to work now…

You’ll see now that we are using the OnElementChanged method to do almost the same as in iOS. So again check if the actual page does have a title or not and when it does, create a new TextView element.
On this Android control we can also indicate that we want to use 2 lines is needed : title.SetMaxLines(2).
And also here we need to pass in the actual page title and adjust the default Xamarin forms rendering view : actionBar.SetCustomView (title, new ActionBar.LayoutParams (LayoutParams.MatchParent, LayoutParams.MatchParent)).

What is different on Android, is that the ActionBar ( where the title is shown ) is shared across all pages. Thus once you’ve manipulated it, it will be fixed for all.
Meaning that when you have navigation and go back in the navigation stack, you’ll see that the set title will no longer change!
To counter this, we’ll need to hook into another event to keep track of this back stack navigation and if needed reapply the title.
This is done by monitoring the Element.Appearing event and when we enter this, reset the page title : ((TextView)actionBar.CustomView).Text = page.Title.

Hope this makes some sense and can help those out there that do need this feature 🙂

As always all the code can be found on my github right here… https://github.com/Depechie/XamarinFormsMultiLineTitle

UWP – Close a Flyout MVVM way with UWP XamlBehaviors

Using a Flyout control in an UWP app is super handy to show contextual actions, but somehow they aren’t very MVVM friendly.
It was easier during windows 8.1 days, but with UWP it’s a hassle.

I’ve seen many solutions on how to tackle this problem, but let you give me mine just to show some other angles.
I’m trying to use the new UWP XamlBehaviors that went Open Source a while back, for all the info take a look here https://github.com/Microsoft/XamlBehaviors.

So the setup, we have a page that has a button – that button will open a flyout. On this flyout we have another button that will trigger some long running process in MVVM ( it’s not in this demo 😛 ).
What we want to do is dismiss the flyout from our MVVM if the process is done.

Here is the XAML code

Some things to note… We are using a MVVM command through binding for the button that is shown on the flyout.
The other thing, is the DataTriggerBehavior! It’s one of the behavior types that is available through the XamlBehaviors and what it allows us to do is perform some action when some data element changes to a certain value.
Here we are monitoring the IsFlyoutClosed boolean of our MVVM ViewModel to see when it’s being set to True. If this happens, we’ll perform an action called CloseFlyoutAction.
This action is a custom one and it’s purpose is to close the current given Flyout, as shown in the code below.

And that’s it… only thing left to do is manipulate the boolean on the ViewModel when you want to close the flyout.

As always an example project is available on GitHub here… https://github.com/Depechie/UWPFlyoutCloseMVVM

How to add a Tag list into WinRT universal apps

** Update: also look at an alternative solution Shawn Kendrot did here: http://visuallylocated.com/post/2015/02/20/Creating-a-WrapPanel-for-your-Windows-Runtime-apps.aspx

Sometimes you like to present a list of items to the user. But the requirements for that list are so, that it must remain compact, wrap at the screen edge and editable in that sense that you can remove items quickly.
This kind of list is often represented by tags, so how do you do this in an universal app, let me show you how!

TagList

First thing that is very important to note, is the fact that we will be using a RichTextBlock with an InlineUIContainer. We do this, because the RichTextBlock handles the screen wrapping/overflow! That will enable us to add tags and each time a new one is added to the list, the RichtTextBlock will validate if it will still fit the current line, if not it will add a new line and wrap.

And to be honest that’s it! Only thing left to do is add the real tags, that are actual Buttons inside the InlineUIContainer. In the current demo application I’m doing this in the code behind of the MainPage file, there is a method called SetTags.

In that method we will first go through the newly selected Tags and search for the corresponding buttons inside the RichTextBlock, when found we remove them.

After that we will be adding all new Tags.

Again a bit the same concept as the removal. For each tag not yet in the current tag list, we create a new button with a specific style and add a click handler that will enable the removal. Once that button is created we add it to the RichTextBlock InlineUIContainer so it will show up on screen.

When the user presses the tag, the click event will fire an the selected tag will be removed from the list.

The actual thing missing from the current implementation, is the fact that it’s not an real control yet… so if anyone feels the urge, please be my guest 🙂

Soure code can be found on my GitHub here…

This is how it looks!

Migrating from SL8.0 ProtectData to RT8.1 PasswordVault

Back in the SilverLight days when you created a Windows Phone app that needed to store user credentials, there was only one good way to do this!
You had to use the ProtectData class with it’s Protect and Unprotect methods.

The reference post about how to do this was given by Rob Tiffany here http://robtiffany.com/encrypting-your-credentials-on-windows-phone-7-5/!

But of course you now want to create a new Universal app and you wonder what the new way of storing credentials in a safe way is today… Well it’s called PasswordVault!
Read about it here http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.security.credentials.passwordvault.aspx.

Big advantage of using PassworVault, is that it will roam the settings across devices! So in other word, if you first installed the Windows Phone app and entered your credentials. Than download the Windows Store app, you’ll no longer need to enter your credentials because the app uses the same Vault and can already read the needed info out of it!

Now let me show you how you implement these 2 options, so you’ll have a clear overview of how to migrate from one to the other.

First up, the use of ProtectData.
What I tend to do is protect all account data in one go by first creating a json string from the given data and storing that as a protected byte array inside a file on the Windows Phone.
Small note: the Account class in the examples below is just a small POCO with UserName and Password properties.

When that is done, you’ll be able to read it out again when needed! Most of the time you’ll do this at app startup.

So you see it’s very easy to store a whole collection of account info in your isolated storage in a secure way!
Now when you upgrade your app to WP 8.1 RT, you’ll want to do this in a different way! By using the PasswordVault to ensure that your credentials are still stored in a secure way AND are roaming across devices.

When you want to use the PasswordVault in your app, you’ll need to select your own app key. Because everything stored and retrieved from the vault is done with that key! This is needed because otherwise, when linking your WP and Win Store app, you won’t be able to read out the same credentials.

Getting all credentials from the vault is done through the FindAllByResource method, supplying the app key. Do note that you’ll need to check for exceptions that can occur by doing this, because if the given app key is not yet present in the vault, you’ll get an exception!
After that, you’ll need to request the password for each credential that you got from the vault! Don’t forget this, because when using the FindAllByResource method the passwords will still be empty. Getting the password is done by using the RetrievePasword method.

So now we already know how to get hold of everything in the vault, but how do we store or remove accounts?
Well there are 2 methods for this, Add and Remove, so as easy as that. Do note there is no Update method.

So there you have it, everything you need to know to convert your apps!

LowlandsWPDev from wp8.0 SL to wp8.1 RT – Tilburg

Last Saturday DotNed and MADN joined hands and did a one day seminar around Windows Phone 8.1 RT development.

So a classic setup of speakers and sessions, in this case 8 speakers with 2 tracks simultaneously done in 2 rooms.

My session was about how to upgrade your existing windows phone 8.0 silverlight apps to windows phone 8.1 RT, in other words what has changed regarding app development and control usage. It also gives a good overview of what is available if you are a starting windows phone developer.

The demos and PowerPoint can be found here…

Windows Phone Image button style

So you are creating your latest windows phone app and would like to add some fancy designed icons or images… But instead of just showing these, they’ll need to react as a button! By the way, we normally use vector data, but that is not always to our disposal. It could be we have a nicely designed icon in several resolutions.

Well that’s easy you think, we’ll just add a button and put that image inside it – here is the code

But when you just use it like this, the image won’t look good! It will have the default button border around it and that’s not something you want.

image

Than you think a little bit about it, maybe search the internet and yes, behold Jeff Wilcox used something back in the wp7 days that could be usefull! An EmptyButtonStyle, it’s a button style stripped to the bare minimum! So you add that and use it – here is the code

But again you’ll notice it’s not perfect… ok it has no visual references anymore to a button, but pressing the image will now also no longer give a visual indication!

image

On wp8, pressing a button, the content will slightly grey out to tell the user he’s pressing that button! So we need to check the state of the button to play with the opacity and enable this visual effect again! Behold the ImageButtonStyle

So when running the app you’ll notice no difference with the empty button style, until you press it! It will now grey out the content a little bit.

As always a test project can be found on github here: ImageButton project

Xbox music integration – windows phone

So you’ve created a Windows Phone app that has something to do with music? Well chances are you can gain some money with it thanks to the Xbox music affiliate program!
All you need to know to get this up and running is available on MSDN here… but let me show you my implementation, because I find the docs on MSDN a bit chaotic.

So first things first, open up a publishers account on Rakuten Linkshare through this url http://www.linkshare.com/join/ This is needed, because they are the ones gathering the click information and doing the payments.

* Pro tip * Note that at one point you’ll need to fill in website info – here you’ll have to put the URL pointing to your app in the windows phone app store! This is important, because that way Xbox music can verify your request ( more on this later on ).

* Pro tip * Be sure to take into account that you’ll need to fill in form W-8BEN if you live outside of the United States, for being in order of payment taxes!

After you filled in all the needed info and your account is in order, open the LinkShare website and navigate to PROGRAMS > Categories – select category Entertainment > Music and look for Xbox Music and press the Apply button on the right side.

LinkShare

When you apply for a new advertiser, you’ll get an email notification stating that it will take 1 till 2 weeks before your application is approved! And here comes the important pro tip from above, this validation is done based on the app url you submitted earlier. So you’ll first need to add a working app to the store.

After a positive review, your app will be approved for generating links to LinkShare. So the coding/integration can begin!
In my app ConcertWall I wanted to show albums from a specific artist and when the user presses the image from that album, it will show Xbox music so you could play/purchase that album.

To get started with using the REST API service of Xbox Music, you’ll need to get a Client ID and Client Secret for your app. This can be obtained via https://datamarket.azure.com/ – you’ll need to register and add the app. All the details and steps are outlined on MSDN here…
With this info you then can set up your first method to interact with the service!

When you want to gather data, you’ll first need to request an access token from the OAuth service before you can perform any REST calls to the Xbox Music service. I’ve packed this call in an async method called RequestAccessToken.

It needs your client id and secret ( the ones you created on the DataMarket.Azure site ), a given scope – this is a fixed string http://music.xboxlive.com all this has to be passed to the token service – this is https://datamarket.accesscontrol.windows.net/v2/OAuth2-13 – as a http POST. You’ll get a response back that contains the needed access token.

This token allows you to do any HTTP Get REST requests to the Xbox Music service for a specific period. In my case I just wanted to show all albums of a given artist. I wrapped this in a method called GetArtistAlbums

The Service Request string is composed of different parts, let me show you each one

  • First the base url: _artistSearch = https://music.xboxlive.com/1/content/music/search?q={0}
    • So we are going to perform a search with a given keyword
  • The keyword: artistName = the input parameter of this method
  • We want albums so add: &filters=Albums
    • You can search for other items, be sure to check out the MSDN documentation
  • Add the access token: _xboxMusicRESTRequest = “&accessToken=Bearer+”
  • Concat with the actual urlencoded token: new Uri(serviceRequest + HttpUtility.UrlEncode(accessToken))

With that in place, you just fire a client.GetAsync() and the response return value will be a JSON string containing all found Albums mathing your search string. I found that this can be a big set with to much hits, so I filter out all albums that don’t have the given artist name in the artists list of each album!

* Pro tip * Do note we aren’t yet earning any money! For this we need to add Deep Links to Xbox music on our phone.

I now present these albums in a list so the user can press the image, with this I’m activating the Deep Link url to Xbox Music on the phone.

Albums

The correct deep link uri for each album is actually already inside the response result we got from our search query, but to gain money through LinkShare we need to modify it!
We need to reroute our request through LinkShare with the correct id’s so that LinkShare can track the requests and if needed award us points!

The correct link format is show below, only thing missing is your affiliate key for Xbox music – this id can be found by generating a link on the LinkShare site for Xbox music after your request for this advertiser has been approved! Just press the Get Link button and look for the http://ad.linksynergy.com/fs-bin/show?id= part it shows you the id!

But how do you use this deep link? Well put a WebBrowser control on your windows phone page and set it Collapsed.

Only thing left is triggering the navigation on this control with the given deep link url!

* Pro tip * Instead of doing this yourself, you can use this XBox music API wrapper ( pcl ) ! It contains all needed REST calls and also provides the possibility to add your affiliate id!

Happy money gaining!

Navigating to same viewmodel but with different data and keep navigation stack correct with MVVM Light

Long title, I know… and even with that the scenario I’m trying to describe isn’t clear yet, so let me explain even more.

In my latest app ConcertWall you can open a Venue and look at the concerts that are available, when you open up a Concert you can – again – go through to the same Venue and pick another Concert to get the details.

Now translated to the technical MVVM background this means: Venue viewmodel A > Concert viewmodel A > Venue viewmodel A > Concert viewmodel B > etc…

But when you try to do this in a normal MVVM Light way, you’ll break the Navigation stack! Because when you’ll navigate back from concert viewmodel B to the venue viewmodel A to the concert viewmodel A, you’ll notice A will no longer be visible but you’ll get B again!

This problem is easy to explain, you only retain one instance of the concert viewmodel and if you do nothing when navigating, only the last loaded datacontext will be shown each time you get on the concert view!

Now how can we fix this, there are several ways ( like Nico Vermeir shows one here ), but I like to use the SimpleIoc functionality that is present in MVVM Light and let it handle my instances instead of adding extra in memory containers!

So how do you get this working, first you’ll need to add a special method inside your ViewModelLocator called GetViewModel<T>

This is actually the real solution, all it does is keep track of all separate instances of a given viewmodel based on a key you provide! So no hassle with keeping track of it myself.

Only thing left to do is using this method when navigating to the viewmodel you want to track based on a key ( in our example the Concert viewmodel ).

Best thing to use as key, is the unique identifier that is present in your data model that needs to be shown on that view ( in our example the Concert ID ) and add that to the navigation URI.

Now when you navigate to the view, you can no longer use the MVVM Light datacontext binding in XAML! This because we’ll need to set it our self through use of the above provided GetViewModel method based on the key that is used in the navigation URI. So in the code behind of the given view, override the OnNavigatedTo method and inject the correct viewmodel datacontext!

I’m also calling a RefreshLayout method to refresh the current data on each view load, but depending on the app scenario this is maybe not needed.

With all that in place, you can go forward and call the same viewmodel with different data over and over, and keep your navigation back stack intact because of the added key inside the navigation URI.

Happy coding!