July 26, 2016 6:04 GMT

Learn How Xamarin Customers Ship Five-Star Apps

Today, we’re happy to announce our new Xamarin Customers website, which highlights our global customers across verticals, use cases, and geographies. From indie developers building their first app to multi-million dollar organizations with hundreds of apps in the pipeline, our customers are creating amazing mobile experiences. To recognize their success, we’ve captured more than 25 customer stories across 12 verticals.

Xamarin Customer logo wall

It’s easier than ever to deliver amazing Xamarin apps for any scenario:

  • Pinterest uses Xamarin Test Cloud to delight Pinners everywhere, guaranteeing its apps look amazing and work without issue on any device for over 100 million users.
  • Coca-Cola Bottling Co. Consolidated is transforming their business with anywhere, anytime accessible field sales apps powered by Xamarin for Visual Studio, Azure, and Visual Studio Team Services.

Our partners play a big role in our customers’ mobile strategy:

  • Info Support took home the 2016 Enterprise Xammy Award for their work with Dutch Railways, creating apps that equip Dutch Railways’ staff to better serve its over 1.1 million daily passengers.
  • Escher Group paired their Xamarin development skills with JudoPayments’ Xamarin SDK to rewrite Ireland’s largest coffee chain’s loyalty apps in C#, resulting in a better customer experience, incorporating technologies like Apple Pay to drive more revenue.

Visit xamarin.com/customers to explore our customer stories, and contact us to share your own.

The post Learn How Xamarin Customers Ship Five-Star Apps appeared first on Xamarin Blog.

July 26, 2016 3:58 GMT

Updated Olo.BuildTools Xamarin Studio Add-In

A couple years back I posted about an add-in we wrote to expose a command to use as part of our build process to grab a snapshot of the current versions of all the tools in the Xamarin Studio build chains. For us this is essential in being able to track how a specific app was built long after versions have been updated on the build server.

With the release of Xamarin Studio 6 the add-in model changed a bit, so add-ins needed to be updated in order to support it. We just published version 2.0 of Olo.BuildTools to the gallery which is built to support Xamarin Studio 6:

Add-In Gallery

The command itself is identical to 1.0, Hat tip to my colleague Andrew Strickland for doing the lion's share of the work there! We left 1.0 published as well for those of you still using Xamarin Studio 5.0.

Hope others find this useful!

July 26, 2016 5:42 GMT

Thoughts on making TinyPubSub a little less tiny

Thoughts on making TinyPubSub a little less tiny

TinyPubSub is a very simple Publish/Subscribe library created mainly for passing events between views in an Xamarin Forms application that uses MVVM. You can read about it at https://github.com/johankson/tinypubsub.
What I'm thinking about doing is extending it with two features
  • Passing of data
  • A stack based recipient model

Passing of data

TinyPubSub only allows for publishing events from one source to many recipients. It was originally create for notifying other views to reload or refresh their data. At first this was pretty much all it was intended to do. But now I can't help myself and I would really like to publish data as well.
This is the original way to subscribe and publish an event.
In the first view model
() => { RebindGui(); });
In another view model
Let's say I want to pass data, it could look like this
(c) => { RecolorDuck( c ) } );
And in the publish part
TinyPubSub.Publish("duck-color-updated", c);

An example

Let's say you're buildning an app for configuring a car. The first page is to choose the model. On this page there is a button to choose your color. The original page simply registers for the color-chosen event and waits happily for that to happen. We then create a generic choose color page that knows nothing about what page that really needs that color. When the color finally is choosen the page fires a color-chosen event and the first page will receive it.
All is fine until you get another subpage that also wants a color choosen. You can solve that in a number of ways. The first being to register different events for different colors choosers and pass an argument to when we create the color picker page. This is messy and could easily get out of hand.
My proposed solution is to create a function where you can state that only the latest registered listener will handle the event.

A stack based recipient model

Enter the stack based recipient model.
The mechanism behind this is simple. The latest registered recipients of a specific event is the only one that will receive an event.
Since all events for a page is deregistered automatically in TinyPubSub it will be simple to reuse the color-picker page multiple times.
To revisit the car example, just before clicking the button for coloring your car door you register to the color-chosen event with the `SubscribeExclusive(...) method.
(c) => { RecolorCarDoor( c ) } );
await Navigation.PushAsync(Resolver.Resolve());
Then it doesn't matter if you have another page listening for the color-chosen event. Only the page before will get the event. And when the page goes out of scope, the subscription for the event will be removed and the page before will get the event instead.
This also means that the ColorPickerPage could check at runtime to see if there are any recipients at all and throw an Exception if there is none.


This is still not implemented. I thought I just write it down first and get some comments on it.
July 25, 2016 4:12 GMT

Preview: Android Nougat is on the Way

Today, we’re excited to release a new version of our Android N Developer Preview, which features bindings to the final APIs of the Android N SDK. The new version includes several exciting features including multi-window UI, direct reply notifications, advanced memory and power optimizations, and more for developers to integrate into their applications.

Android N Hero

Get Started

Start the Android SDK Manager:

  • Xamarin Studio, use Tools > Open Android SDK Manager
  • Visual Studio, use Tools > Android > Android SDK Manager

Install the latest Android SDK tools; these are listed under Tools:


Install Android Nougat (API 24) SDKs and Device Images:

You must install Android SDK Tools revision 25.1.7 or later, SDK Platform-tools 24 or later, and SDK Build-tools 24.0.1. For more information about using the Android SDK Manager to install the Android SDK, see SDK Manager.

Finally, download the latest preview Xamarin.Android packages for Visual Studio or Xamarin Studio.

When is Nougat coming out?

As of this posting, the final release of Android N Developer preview has been released and developers can start publishing apps to devices running Android N at the official API level if your users have opted into the Android Beta program. This will have your app ready for Android N when it is officially released later this year in Q3. Head over to Google’s preview overview page for more details.

Google’s Android N Timeline
Android N Updates

Important Behavior Changes

Android N introduces several behavior changes that could impact your application. These include new Doze optimizations for battery and memory improvements, background optimizations (including the deprecation of the CONNECTIVITY_ACTION broadcast), permissions changes, and several others that you can read about on the Android N preview portal. One of the more substantial changes to the platform is a new restriction of applications using non-public APIs such as SQLite, libcrypto, and many more. Be sure to test your application and libraries on Android N to ensure compatibility.

Learn More

Head over to our Xamarin Android N Developer Preview guide to read up on all of the latest features and for the latest downloads of our Android N Preview for Xamarin developers. Then be sure to check out our Android N samples on GitHub.

The post Preview: Android Nougat is on the Way appeared first on Xamarin Blog.

July 25, 2016 2:00 GMT

Gone Mobile 37: Hybrid Xamarin Apps with Drew Colthorp and Shawn Anderson

Hybrid apps with Xamarin? You bet! In this episode we’re joined by Drew Colthorp and Shawn Anderson to talk about why and how they converted their hybrid app, written in Ember, from Cordova to Xamarin.

Hosts: Greg Shackles, Jon Dick

Guests: Drew Colthorp, Shawn Anderson


Thanks to our Sponsors!


Raygun Pulse is now available for mobile - Real user monitoring for your mobile apps! Get deep detail into how your mobile applications are performing for your users.

July 24, 2016 8:00 GMT

File Nesting in Xamarin Studio

With recent versions of Xamarin Studio it is not currently possible to nest files without directly editing the project file. In the past it was possible to drag and drop a file so it was then nested inside another file.

Solution window with nested files in Xamarin Studio

Visual Studio also does not support nesting files by using drag and drop however Mads Kristensen created a File Nesting extension that adds support for manual and automatic nesting of files within Visual Studio. There is a demo video of the File Nesting extension that shows the extension being used with Visual Studio. This extension has now been ported to Xamarin Studio and is available from the MonoDevelop Add-in Repository.

Let us take a walkthrough of the features of the File Nesting addin for Xamarin Studio.


  • Manual file nesting
  • Manual file un-nesting
  • Automatic file nesting of selected files based on rules
  • Automatic file nesting when files are added to a project
  • Options to specify which file nesting rules are applied


  • Xamarin Studio 6.0 or MonoDevelop 6.0.

Manual File Nesting

To manually nest a file select it in the Solution window then right click and select File Nesting – Nest Item…

Manual file nesting - nest item context menu

This will open a file nesting dialog where the parent file can be selected.

File nesting dialog

Select the parent file and click OK to nest the file under that parent file.

Manual file nesting result in solution window

You can also nest multiple files under a parent by selecting multiple files in the Solution window and selecting the Nest Item menu.

Manual File Un-nesting

To un-nest a file select it in the Solution window then right click and select File Nesting – Un-nest Item.

Manual file nesting - un-nest item context menu

The file will then be un-nested from its parent.

Manual file un-nesting result in solution window

Automatic Nesting Rules

The file nesting rules are available from the Preferences dialog.

File nesting rules in preferences

Each rule has a tooltip which will show more detailed information about what the rule does.

Enable auto-nesting

The Enable auto-nesting option will enable or disable automatic file nesting when a file is added to a project.

Enable extension rule

This rule will nest files added with an extra extension under their corresponding parent file. For example MyView.xaml.cs nests under MyView.xaml.

Nested file using extension rule

Enable interface implementation rule

This nests C# interface implementations under the corresponding interface based on the filename. For example, if there is an interface file IMyInterface.cs then a new file called CustomMyInterface.cs will be nested under the IMyInterface file.

Nested file using interface implementation rule

Enable known file type rule

This nests certain known files types. For example, MyPage.ts will be nested under MyPage.html.

Nested file using known file type rule

Enable path segment rule

This nests files with an added path segment under its parent. For example, MyFile.Designer.cs nests under MyFile.cs.

Nested file using path segment rule

Automatic Nesting of Selected Files

To automatically nest files, based on the enabled file nesting rules, select the files, or folder, or project, then right click and select File Nesting – Auto-nest selected items.

Auto-nest selected items context menu

This will then apply the enabled file nesting rules to the selected files.

Automatic File Nesting on Adding Files

To enable automatic file nesting when files are added right click the project and select File Nesting – Enable automatic nesting.

Enable automatic nesting context menu

A check box will be displayed next to this menu item if this feature is enabled. Now when a file is added the enabled nesting rules will be applied and the file will be automatically nested.


The File Nesting addin is available from the MonoDevelop Add-in Repository on the beta channel. To install the addin open the Add-in Manager, search for the File Nesting addin, then click the Install button.

File Nesting addin in addin manager window

After installing the addin Xamarin Studio will need to be restarted for the addin to work correctly.

Source Code

July 22, 2016 5:45 GMT

New Xamarin Dev Days Cities Announced!

Last year, hundreds of developers joined us at Xamarin Dev Days in dozens of cities around the US to learn cross-platform mobile development. The events were such a success that we’re bringing it back this year and taking it global! The first Xamarin Dev Days of 2016 in Milan and Mexico City were great, with a full house at both locations, where every developer went home with a goodie bag and tangible knowledge of how to build, test, and monitor native iOS, Android, and Windows apps with Xamarin.

XDD Milan 2016

What are Dev Days?

Screen Shot 2016-07-22 at 13.19.22Xamarin Dev Days are community run, hands-on learning experiences. More than just your average hackathon, they are free, day-long events focused around learning how to build native iOS, Android, and Windows apps with C#, Xamarin, and partner technology through valuable sessions from Xamarin, our partners, or your local developer community leaders.

After a morning of learning how to build beautiful, cloud-connected mobile apps with Xamarin, you’ll get a chance to put your new knowledge into practice with a hands-on workshop that walks you through the process of building your first cloud-connected, cross-platform mobile app. Xamarin experts will be there to help you get up and running, debug code, and answer any questions you may have.


Announcing More Cities!

8/06: Gurgaon, India
8/09: Ho Chi Minh City, Vietnam
8/20: Washington, DC
8/20: Kuala Lumpar, Malaysia
8/20: San Francisco, California
8/20: Bangalore, India
8/27: New York, NY
8/27: Kochi, India
9/03: Kolkata, India
9/03: Brisbane, Australia
9/10: Sevilla, Spain
9/16: Pisa, Italy
9/17: Hyderabad, India
9/17: Kitchener, Canada
9/24: Thiruvananthapuram, India
9/24: Curitiba, Brazil
9/24: Montreal, Canada
9/30: Bristol, UK
10/15: Houston, TX
10/29: Strasbourg, France

Use the map below to find an event near you, or head on over to our Xamarin Dev Days website for a full list of current Xamarin Dev Days cities around the world.


Get a Xamarin Dev Days in Your City

If you didn’t see a city near you on the map but are interested in organizing an event locally, apply as a Xamarin Dev Days host! We’ll provide you with everything you need for a fantastic Dev Days event in your town, including all of the speaker content and lab walkthrough, a hosting checklist, and swag goodies to give away to all of your attendees.

Sponsoring Xamarin Dev Days

We’re working with tons of Xamarin Partners and community members’ companies around the world to help facilitate Xamarin Dev Days. If your company is interested in participating, apply to be a sponsor and get global recognition as a Xamarin Dev Days contributor, as well as access to our worldwide developer community.

The post New Xamarin Dev Days Cities Announced! appeared first on Xamarin Blog.

July 22, 2016 12:06 GMT

Back to School Part 2: Revenge of the Custom Bindings!

Late last summer I wrote a post on creating a custom bindable property using Xamarin.Forms. I titled it “Back to School” because I wrote it around … well … back to school time. Since then however, the Xamarin.Forms team has seen fit to deprecate the function I wrote about that creates the bindable property … and we’re still in the middle of summer!

Ugh – it hasn’t even been a year!

Well, I guess it’s only right of me to update a partially out of date post with the name “back to school” in it … So welcome to Back to School Part 2: Revenge of the Custom Bindings!

I won’t go as in-depth as I did in Part 1, as the details I talk about in that post still stand – however, the API signature to create the binding has changed a bit, and that’s what I want to talk about here.

The API Changes

For the sake of example, I’m going to call the non-deprecated API the “new” API, although it has been around for a while.


public static BindableProperty Create(
    string propertyName, 
    Type returnType, 
    Type declaringType, 
    object defaultValue, 
    BindingMode defaultBindingMode = BindingMode.OneWay, 
    BindableProperty.ValidateValueDelegate validateValue = null, 
    BindableProperty.BindingPropertyChangedDelegate propertyChanged = null, 
    BindableProperty.BindingPropertyChangingDelegate propertyChanging = null, 
    BindableProperty.CoerceValueDelegate coerceValue = null, 
    BindableProperty.CreateDefaultValueDelegate defaultValueCreator = null);


public static BindableProperty Create<TDeclarer, TPropertyType>(
    Expression<Func<TDeclarer, TPropertyType>> getter, 
    TPropertyType defaultValue, 
    BindingMode defaultBindingMode = BindingMode.OneWay, 
    BindableProperty.ValidateValueDelegate<TPropertyType> validateValue = null, 
    BindableProperty.BindingPropertyChangedDelegate<TPropertyType> propertyChanged = null, 
    BindableProperty.BindingPropertyChangingDelegate<TPropertyType> propertyChanging = null, 
    BindableProperty.CoerceValueDelegate<TPropertyType> coerceValue = null, 
    BindableProperty.CreateDefaultValueDelegate<TDeclarer, TPropertyType> defaultValueCreator = null) where TDeclarer : BindableObject;

Buy Why?!?

At first glance the old API looks a bit messier, but once you dig in you find that in fact it really is more elegant. The generics in the old signature provide a means to strongly type everything that follows (plus the added bonus of IDE provided intellisense). Not to mention there are less parameters – we don’t have to explicitly define the return and declaring type.

So if the old API was so great – then why did it change? That’s exactly what I asked Twitter. And Twitter did what Twitter does … Adam Patridge (fellow Xamarin MVP) came back with the answer:

If you click on through to Jason Smith’s & Adam’s conversation, it turns out that there’s a ton of bloat introduced with the old

API by iOS and its AOT compiling (interested in Xamarin.iOS at that level? Here you go.)

OK – so the API is deprecated for our own (and our app’s) good! So let’s now look at using the other / new one.

Creating the Bindable Property

The API signature is pretty straight forward, with the first 4 parameters being required (and I always specify the default binding mode, the fifth parameter, as well – if only to be explicit).

For this example, imagine that we’re extending a normal

control, and adding a boolean property to it that we want to be able to bind to our view model. The class will be called
and the property will be called
. (Original, I know.)

The bare minimum we have to do to create the binding is the following:

public bool IsNew
    get { return (bool)GetValue(IsNewProperty); }
    set { SetValue(IsNewProperty, value); }

public static readonly BindableProperty IsNewProperty = BindableProperty.Create(

After that in the

function are all of the delegates. Their purpose stays exactly the same. The only thing that changes is that the parameters representing the value of the binding (in our case the boolean) are no longer strongly typed.

Let’s take a quick look at them:

  • public delegate bool ValidateValueDelegate (BindableObject bindable, object value);
  • public delegate void BindingPropertyChangedDelegate (BindableObject bindable, object oldValue, object newValue);
  • public delegate void BindingPropertyChangingDelegate (BindableObject bindable, object oldValue, object newValue);
  • public delegate object CoerceValueDelegate (BindableObject bindable, object value)
  • public delegate object CreateDefaultValueDelegate (BindableObject bindable);

So when implementing these delegates,

will always be the thing that’s getting bound to … or our
instance. Then we’ll have to cast any “value” parameters to the type of value we’re dealing with. For a full explanation of what each of these delegates does and the order they are invoked – see the original post.


That’s it! The API signature that provided the ability to create a bindable property, including delegates to handle the verification and changing of the value of the property in a strongly typed manner is gone. It’s gone for a good reason – it led to bloating app sizes.

We’re still able to create the custom binding – but not in a strongly typed manner any longer. So we’re trading off having to do a lot of casting in exchange for smaller app sizes.

I’ll take it.

July 21, 2016 3:16 GMT

Introducing Stack Overflow Documentation

Xamarin and Microsoft are excited to be a part of the launch of Stack Overflow Documentation. This new feature brings the same collaborative approach from Stack Overflow’s question-and-answer system to developer documentation.
stackoverflow documentation

Stack Overflow Documentation provides a set of edit and review tools that lets the community write example-focused documentation to complement our existing developer portal and samples at developer.xamarin.com. Stack Overflow badges and reputation are supported, so every contribution you make is recognized; the more docs you contribute, the more rep you earn!

How does it work?

The new site will be organized by Stack Overflow tags (such as Xamarin.iOS and Xamarin.Android) which will contain documentation topics with many examples.

Browsing the documentation is as easy as using Stack Overflow: you can navigate by tag, topic, or search. If you can’t find the documentation you’re looking for, suggest someone write it (or if you know about a particular subject, write it yourself).

How to Contribute

Stack Overflow users can:

  • Suggest topics that they would like to see documented, for others to write.
  • Create a topic they are knowledgeable on, and immediately add examples.
  • Add examples to existing topics.

Each topic can have a number of examples to demonstrate how to accomplish different tasks. Examples can have the following four elements:

  • Examples: Topics should always include working code examples.
  • Syntax: Add method signatures if they aren’t obvious.
  • Parameters: Explain what parameters are for and any constraints they must adhere to.
  • Remarks: Describe any additional rules or pitfalls that aren’t covered in the code examples.

Submissions will be peer-reviewed; the site includes the ability to share drafts and chat with other contributors before an example is published.

Get Started

Xamarin tags are set up and ready for contributions, as this screenshot demonstrates:

Xamarin.iOS on Stack Overflow Documentation

We’re excited to see what great examples our developer community create and share!

Visit stackoverflow.com/documentation to get started today.

The post Introducing Stack Overflow Documentation appeared first on Xamarin Blog.

July 21, 2016 9:18 GMT

Introducing Xamarin.iOS to Objective-C/Swift developers

A few months ago I had the chance to showcase Xamarin.iOS to pure Objective-C/Swift developers, within a local group called NSCoder Sevilla.

Instead of making slides I thought it’d be more interesting to build a small app which’d do the same, as well as serving as a playground to showcase some topics: managed vs. native call stacks, Xamarin.Forms, Xamarin Workbooks (Inspector mode), etc. I think the most interesting piece for them was inspecting the app in real time with this last one.

Microsoft/Xamarin❤ iOS demo app. Tap the image to play with it!

The full codebase can be found here. It may be interesting as well for anyone who’s invited to a similar scenario:-)

PS: Thanks Diego Freniche for inviting me to this!

July 20, 2016 4:07 GMT

Build C# and F# Apps on Your iPad with Continuous Mobile Development Environment

It doesn’t matter if you’re on a Windows or a macOS machine, you have access to amazing IDEs to build iOS, Android, Mac, and Windows apps and libraries with Visual Studio and Xamarin Studio. But, what if you could take all of your code on the go and with you everywhere you go? What if you could open up a code file, library, or Xamarin.Forms project on your iPad and start coding with a full professional mobile development environment with IntelliSense powered by Roslyn? That’s the experience that Frank Krueger, Xamarin MVP, delivers with his new app, Continuous Mobile Development Environment, a professional C# and F# IDE for your iOS devices.


Built with Xamarin

Frank Krueger has been developing apps with Xamarin since it first came out. He’s seen great success as an independent developer with apps including iCircuit and Calca. Continuous demonstrates the full potential that’s unlocked for .NET developers through Xamarin, with full API access across all platforms and the power of .NET.

Powered by Open Source

Powered by the open source .NET compiler platform as a service Roslyn, Continuous offers full syntax highlighting and code completion as well as documentation for over 60,000 symbols. Krueger was able to deliver rich F# support with the open source FSharp Compiler, and to bring Continuous full circle and deliver support for .NET’s standard library, all iOS APIs, and support for Xamarin.Forms, it leverages Mono and the now open sourced Xamarin.iOS and Xamarin.Forms. It’s amazing to see what can be built with these open source technologies!


Professional Development Environment

As a professional development environment, Continuous is lightning fast, has an interactive output window to see your app running live, automatic and constant debugging, and works completely offline. If that wasn’t enough, Continuous deeply integrates into iOS features and has a custom keyboard accessory for quick access to much needed keys for C# and F# development. Continuous doesn’t stop there, though—it also enables developers to carry on development in your favor desktop IDEs, Visual Studio and Xamarin Studio. You can share a single file, zip an entire solution, or collaborate with other iOS apps to synchronize with Git.

Try Continuous Yourself

You can learn more about Continuous at continuous.code and learn more about its development and release on Krueger’s blog. We want to congratulate Frank on his release of Continuous; we can’t wait to see what he and all developers building apps with Xamarin come up with next. To learn more about all of the open source projects at Xamarin, visit open.xamarin.com

The post Build C# and F# Apps on Your iPad with Continuous Mobile Development Environment appeared first on Xamarin Blog.

July 19, 2016 6:27 GMT

Explore iOS 10, tvOS 10, watchOS 3, and macOS Sierra Previews Today

Apple announced major updates to all of their operating systems and a smattering of new APIs for developers to explore at this year’s WWDC conference. sdk-icon-90x90_2xWe are excited for Xamarin developers to get their hands on these new APIs to start building beautiful native apps in C#, so today, we’re releasing our first set of previews for developers to start exploring iOS 10, tvOS 10, watchOS 3, and macOS Sierra along with supporting Xamarin-specific documentation to get you started.

iOS 10

iOS 10 has something for everyone. SiriKit unleashes the power of Siri for developers to integrate unique experiences into their mobile applications to enhance a slew of services. Notifications have been completely overhauled to schedule notifications based on geo-fencing or time and a new UI framework to allow enhanced customization has been added. This is just that start, as there are new APIs unlocked in HealthKit, HomeKit, Core motion, Foundation, Core Data, and many more as well. To get started, browse through our Introduction to iOS 10 documentation.


tvOS 10

Bring your apps to life on the big screen with the latest additions to tvOS including ReplayKit to live broadcast game play, PhotoKit to share photos with iCloud Photo Library and your apps, and easily integrate multipeer connectivity to your iOS apps. To get started, check out our Introduction to tvOS 10 documentation.

watchOS 3

Take advantage of the latest watchOS release, which dramatically speeds up performance and navigation of all apps. Performance is one thing, but there are also several new APIs to play with, including Fitness and Motion with access to real-time heart rate data, gyroscope, and accelerator. Enhance your existing apps with direct access to the Digital Crown, speaker audio, in-line video, SpriteKit, SceneKit, Apple Pay, and camera data from HomeKit-enabled accessories! You can get started today with our Introduction to watchOS 3 documentation.

*This initial release of watchOS 3 has a subset of the final APIs that will be available in the future.

macOS Sierra

hero-macos_medium_2xThese Apple previews aren’t just about mobile devices, as you can also start integrating the latest APIs in macOS Sierra (10.12) into your Xamarin.Mac applications. Our Introduction to macOS Sierra documentation is a great place to start.

Installing the Previews

You can download the Previews for Xamarin Studio on macOS directly from the Xamarin Developer site for each OS: iOS 10, tvOS 10, watchOS 3, and macOS Sierra. You will need to ensure that you have the latest Xcode 8 Beta installed, which can be run on macOS 10.11.5 (El Capitan) or newer for iOS, tvOS, and watchOS, and macOS Sierra for macOS Sierra development. Upcoming previews will add even more support for these platforms, including support for Visual Studio.

The post Explore iOS 10, tvOS 10, watchOS 3, and macOS Sierra Previews Today appeared first on Xamarin Blog.

July 18, 2016 8:41 GMT

Effects with XAML

In this excellent article, Nish Anil describes how to modify controls using Effects – a lighter weight approach than creating custom renderers.  His examples, however, are all in C#, so I decided to translate them into XAML. red slider

To begin I created a new Xamarin.Forms project named xamlEffects.  There are two parts to creating the effect.  The first is platform dependent.  Optionally, create a folder in the iOS project named Platform.  In that folder, add a file named RedSliderEffect.cs.  You’ll also create files named BlueSliderEffect and GreenSliderEffect.

This code is right out of the original article:

[assembly: ResolutionGroupName(“EffectsSample”)]
[assembly: ExportEffect(typeof(RedSliderEffect), “RedSliderEffect”)]
namespace xamlEffects.iOS {
    public class RedSliderEffect : PlatformEffect {
        public RedSliderEffect() {

        protected override void OnAttached() {
            var slider = (UISlider)Control;
            slider.ThumbTintColor = UIColor.FromRGB(255, 0, 0);
            slider.MinimumTrackTintColor = UIColor.FromRGB(165, 165, 255);
            slider.MaximumTrackTintColor = UIColor.FromRGB(14, 14, 255);

        protected override void OnDetached() {


Notice that we override two methods: OnAttached and OnDetached.  The idea is that the effect extends the control, and so we attach the effect to the control we wish to extend and then detach and clean up if needed after we’re done.

In this code, we’re setting the slider to a red dot on a blue line.

The important thing to notice are the two attributes.  The first, ResolutionGroupName is only entered once per program.  The second, ExportEffect is used once per effect.  The name of the effect is the concatenation of the two; in this case EffectsSample.RedSliderEffect.

The PCL  and the XAML

In the PCL we’ll create a class that derives from RoutingEffect for each effect we create.  All this class needs to do is to pass up to the RoutingEffect the name we just created.,

using System;
using Xamarin.Forms;

namespace xamlEffects {
public class RedSliderEffect : RoutingEffect {
public RedSliderEffect()
base(“EffectsSample.RedSliderEffect”) {

Now we can turn to the XAML.  We add a slider to the page, and then within the slider tags we need to add a RedSliderEffect to the Slider’s Effects collection.  This is done in the standard fashion for XAML:

                     <local:RedSliderEffect />

(Note that you’ll need to declare the “local” name space using the current assembly),

That’s all there is to it.  This allows for significant changes to a control without creating custom renderers, a meaningful savings in development time and complexity.

Adding A Second Slider

You may very well want more than one slider with the same effect, but perhaps different colors.  To do so, create a second effect in the platform dependent code. This is just like the first one, except, as noted, it has only one annotation:

[assembly: ExportEffect(typeof(BlueSliderEffect), “BlueSliderEffect”)]
namespace xamlEffects.iOS {
public class BlueSliderEffect : PlatformEffect {
public BlueSliderEffect() {

You’ll need a BlueSliderEffect.cs class in the PCL (just like the red slider effect but replacing “red” with “blue” (!)

Finally, in the Xaml, create a second slider,

          <local:RedSliderEffect />

          <local:BlueSliderEffect />

red and blue slider


July 18, 2016 6:49 GMT

Podcast: Tools for Creating & Designing Five Star Apps

This week on the Xamarin Podcast, Mike James and I share the tools and processes we use to create and design beautiful, five-star cross-platform apps, including Sketch, Zeplin, Paintcode, and Bitrise.

Subscribe or Download Today

Knowing the latest in .NET, C#, and Xamarin is easier than ever with the Xamarin Podcast! The Xamarin Podcast is available from iTunes, Google Play Music, and SoundCloud. Do you have an interesting story, project, or advice for other .NET mobile developers? If so, we’d love to share it with the Xamarin community! Tweet @pierceboggan or @MikeCodesDotNet to share your blog posts, projects, and anything else you think other mobile developers would find interesting. Be sure to download today’s episode tools for creating and designing five star apps, and don’t forget to subscribe!

The post Podcast: Tools for Creating & Designing Five Star Apps appeared first on Xamarin Blog.

July 16, 2016 4:36 GMT

View Model First Navigation Part 2 – The Devil’s In The Details

The previous post on view model first navigation within Xamarin.Forms showed how to create a navigation service that associated a view to view model, kept track of those associations, provided functions to navigate between view models, and had the ability to instantiate a view based on which view model was being navigated to.

In other words, it allowed navigation to a

just by having a view model say it wanted to show another view model.

That’s some pretty sweet stuff!

The only problem with the navigation service, as implemented in the previous post, is that it didn’t work with master detail layouts. Not so sweet after all. Not to worry though – we’re going to right the ship and update the service so we can handle master detail pages in addition to tab and plain ‘ol navigation pages!

Along the way we’re going to add some convenience functions to the navigation service and answer some common questions I have been getting about it. Before diving in too deep, if you haven’t already, please read the previous post on VM First navigation to get up to speed on what we’ll be talking about here.

You can find the full implementation of the view model first navigation library on my GitHub here.

Adding Master/Detail Navigation

I have to say, adding the functionality to navigate between different detail pages from a master page proved to be more tricky than I had originally thought it would be. I thought I’d only have to find the

as the
, load up the view corresponding to the view model I wanted to show, then set the
property. Easy. Well, it is – kind of. The problem is there are a lot of little details that need to be accounted for along the way – the devil’s in the details, so to speak.


Detail Devil #1 – New Navigation Function

Since swapping out a detail page is not the same as

, we need to add a new function to the service’s interface with the definition being:

void SwitchDetailPage(BaseViewModel viewModel);

Easy enough – the implementation of that with our existing NavigationService class then looks like this:

public void SwitchDetailPage(BaseViewModel viewModel)
    var view = InstantiateView(viewModel);

    Page newDetailPage;

    // Tab pages shouldn't go into navigation pages
    if (view is TabbedPage)
        newDetailPage = (Page)view;             
        newDetailPage = new NavigationPage((Page)view);

    DetailPage = newDetailPage;

There are a couple of interesting things going on in that function. The first is that we’re checking if the page we want to swap out is derived from a

. If it is not, then we’re going to wrap the page within a
– so we can get a nav bar on top for a heading and the familiar stack navigation. I can’t imagine a scenario where we’d want to have a
as a root of a navigation stack.

The second interesting thing is the

property, whose implementation is:

// Because we're going to do a hard switch of the page, either return
// the detail page, or if that's null, then the current main page       
Page DetailPage
        var masterController = Application.Current.MainPage as MasterDetailPage;

        return masterController?.Detail ?? Application.Current.MainPage;
        var masterController = Application.Current.MainPage as MasterDetailPage;

        if (masterController != null)
            masterController.Detail = value;
            masterController.IsPresented = false;
            Application.Current.MainPage = value;

Now we’re starting to see some of the little details pop out that made implementing this a bit more involved than I originally thought. I did not want to have

be tightly coupled to having a
in the UI. So when getting the
, it checks to see if the app’s current main page is a
, and if so, returns its
page. If not, it returns what ever is set as the app’s main page. The same thing, but in reverse, for set – if there is a
set in the UI – its
page gets set. If there is not – the application’s root page gets replaced.

In other words – the

needs to take into account what happens when a
is both present, and when it is not.


Detail Devil #2 – Obtaining The Proper Xamarin.Forms.INavigation Reference

Every single

object within
has a reference to an
property. However, if you try to perform a navigation on one that isn’t valid (like doing a push onto a
that’s not part of a navigation stack) – an exception will occur. Since we don’t want our view models to know whether they’re hosted within a
, the
of a
or just a regular navigation stack – our navigation service will need to abstract that away from them.

Within the navigation service, we need to come up with a hierarchy of checking the type of our app’s main page and then returning the appropriate

object before we do any navigation operations. That’s being done in the
property, and it looks like this:

INavigation FormsNavigation
        var tabController = Application.Current.MainPage as TabbedPage;
        var masterController = Application.Current.MainPage as MasterDetailPage;

        // First check to see if we're on a tabbed page, then master detail, finally go to overall fallback
        return tabController?.CurrentPage?.Navigation ??
                             (masterController?.Detail as TabbedPage)?.CurrentPage?.Navigation ?? // special consideration for a tabbed page inside master/detail
                             masterController?.Detail?.Navigation ??

It’s not as elegant as I’d like it – but it does the job. First it tries to see if the main page is a

. If it’s a
, it will return the
for the current page shown in one of the tabs.

However, things get weird if it’s a

… first thing we do is check whether or not the current displayed page is a
– then if so follow the routine as above. Otherwise return the
from the displayed

Finally, if it’s neither – just return the main’s navigation.

Alright – we’re making progress … we’re able to set the Detail property of the

and also get at the proper
reference. But how do we keep track of all the view models that make up the various detail pages?


Detail Devil #3 – Keeping Track

On to how we’re going to keep track of the various view models that can be navigated to from the view model that backs the

. This one is actually pretty easy right? Create a custom model class that holds a description of the view model for potential display and then the type of the view model. Put that into a collection of some sort for binding – away we go.


Remember the signature of the method which performs the detail navigation for us looks like:

void SwitchDetailPage(BaseViewModel viewModel);

Hmm… we’re sending it a fully instantiated view model, so if we’re to have a regular

property in this new model class, that leaves the door open to the type not being of a

OK… so we’re going to need to constrain the view model type to be of

within our new model class… and we’ll do that through a new interface and class. The interface will look like:

public interface IMasterListItem<out T> where T : BaseViewModel

And the implementation of that interface will look like:

public class MasterListItem<T> : IMasterListItem<T> where T : BaseViewModel
    public string DisplayName { get; set; }

    public MasterListItem(string displayName)
        DisplayName = displayName;

By using a little covariance here we’re constraining our model class to always hold types derived from

. So populating a list (that we’ll eventually bind to a
) will look a bit like this:

AvailablePages = new List<IMasterListItem<BaseViewModel>>();
AvailablePages.Add(new MasterListItem<NormalOneViewModel>("Normal Nav"));
AvailablePages.Add(new MasterListItem<RootTabViewModel>("Tab Pages"));

Then, when we’re ready to perform some navigation, the code to do so will look like this:

// Get the view model type
var viewModelType = itemToNavigate.GetType().GenericTypeArguments[0];

// Get a view model instance
var viewModel = Activator.CreateInstance(viewModelType) as BaseViewModel;

// Perform the switch

above is a
object. Generally that variable will come from a
property on a

That’s It!

All in all, not too bad, right? There were quite a few little details that needed to be ironed out before we could implement the master/detail page view model first navigation – such as making sure

’s don’t end up nested in a
, finding the correct
object to perform the actual navigation, and figuring out how to store view model types to provide easy access to them when navigating – but once worked out – the service works like a charm!

To view the service along with a working model – view the GitHub project here.

Bonus! Some Convenience Features

As long as I was in the navigation service, I added some minor convenience features to make it easier to use. The largest being the ability to send an action along with a

function. This way one could invoke a function within the target view model to perform some initialization. The implementation looks like the following:

public async Task PushAsync<T>(Action<T> initialize = null) where T : BaseViewModel
    T viewModel;

    // Instantiate the view model & invoke the initialize method, if any
    viewModel = Activator.CreateInstance<T>();

    await PushAsync(viewModel);

And invoking that function would look like:

await _navService.PushAsync<TabOneChildViewModel>(
    (vm) => vm.InitializeDisplay("Title from initialization routine"));


Finally I wanted to answer some questions I have received since posting the original article on view model first navigation.

  • Why use Splat to locate the navigation service?
    • The reason I’m using Splat here is that it provides an easy means to locate the navigation service – and it will keep the nav service in memory too. The built-in Xamarin.Forms dependency service would create it new each time it resolves it, which means we’d have to run through the initialization routine where it associates views to view models each time. Ideally a proper IoC container would be used and the nav service would be injected into the constructor of the view models instead of using a service locator.
  • Why do you “hard code” in views as starting points in the app’s main XAML?
    • While one could work around this, I find it easier to be more explicit as to what is being displayed in the start by declaratively saying which views go where. Makes the code easier to understand for somebody else picking it up for the first time.
July 15, 2016 5:36 GMT

Contest: Add an Azure Backend to Your Mobile App

All apps need a backend, and Azure Mobile Apps makes it simple to add a backend to your mobile application. From no-code backends with Azure Easy Tables to full .NET backends with ASP.NET Web API, Azure has a backend for any kind of mobile app. Once you’ve built your backend, it’s time to consume it from a mobile app, and thanks to the App Service Helpers library, adding a backend to your mobile app can be done in as little as four lines of code.

In this contest, we invite you to add an Azure Mobile Apps backend to your app to win a Xamarin t-shirt!

How to Enter

1. Create a new Azure Mobile App:

2. Connect your mobile app to the cloud.

3. Tweet a short video clip of your Xamarin app connected to an Azure Mobile Apps backend with the hashtags:

  • #Xamarin AND #AzureMobile

Xamarin T-Shirts

Pro Tip: Easily add a no-code backend to your mobile app with just four lines of code in five to ten minutes with App Service Helpers, or follow our guides on adding a backend with Azure Easy Table.


All submissions must be made by Monday, July 25 at 12 pm EST. A valid entry consists of a tweet containing the hashtags #Xamarin AND #AzureMobile, along with a short video clip of your app connecting to an Azure Mobile Apps backend. A valid entry will win one Xamarin t-shirt. Limit one entry per person. To be eligible, you must follow @XamarinHQ to enable us to DM you for private follow up. Please allow up to three weeks for us to verify entries and collect shipping information to send your Xamarin t-shirt. There is no purchase necessary to enter the “Add an Azure Backend To Your Mobile App” contest.

The post Contest: Add an Azure Backend to Your Mobile App appeared first on Xamarin Blog.

July 14, 2016 1:12 GMT

The road to being a Xamarin Certified Developer

For the past time I have been enrolled in Xamarin University with as main goal to verify if the knowledge I had gained by learning myself was the right way. And of course, while I’m at it get certified in the process. In this post I would like to tell you about my experience with University and how you can get started today as well! Not a very technical post this time, so skip this one if you’re looking for that!

So, what is it?

Let’s get something out of the way immediately; Xamarin University is awesome, a bit expensive at about 1800 dollars per year if you are a one-man developer, but awesome.

If you’re used to a Pluralsight, Channel 9 or even YouTube then you’re om for a treat! Xamarin University is not just static videos which you can watch and skip you as you like – although they are available! – they are actual live classes! With actual instructors and the opportunity to ask questions etc. So that is really great!

This also allows for some cool interactions, some instructors start off by greeting everyone and checking where everyone is from and also be prepared for flash quizes! Almost all classes have some individual of class exercises so you get the hang of the subject right away instead of just listening passively.

Besides that you can watch back the videos, do some self-guided classes (with the same flash quizes and exercises) and.. GET CERTIFIED!

Another caveat of this method is that attendance is required for the classes that are required for certification. You cannot start the exam until you have attended all of the mandatory classes. Which are awesome, so no worries there!

Getting to it!

Once you have signed up, the first thing you need to do is specify the times you are available for classes. If you’re in Europe, like me, then some time slots aren’t ideal. But hey, they try their best! And if you really can’t find any suitable time slot you can request a separate session which does suit you. Keeping this in mind it might take you a while to follow all the courses you want, unless you are willing to follow classes which happen in the middle of the night local time.

Choosing preferred time slots
Choosing preferred time slots

Then when you look around you have several pages to point you in the right direction depending on what you main goal is. Also there are some classes which are recommended to follow first. One that is more or less mandatory is the ‘Orientation and Welcome [XAM101]’. This explains all basics kind of like I’m doing now!

You may notice the XAM101 tag at the end. This is a coding system which gives you a hint about the subject and the level of expertise that is required before following this class. These are the prefixes available today:

  • XAM; Xamarin general, mostly in the form of Xamarin Forms and cross-platform stuff
  • IOS; targeting Xamarin.iOS
  • AND; targeting Xamarin.Android
  • CSC; in-depth C# concepts
  • ENT; enterprise, targeting enterprise solutions
  • FSC; for you scarce F# developers out there
  • XTC; you won’t get high, but you’ll learn everything about Test Cloud and testing in more general

These are all separate tracks. Or some of them can be combined to a track to achieve some goal like certification. The number behind it tells you something about the expert level. I’m not sure on the details, but as a general rule: the higher the number, the more guru you need to be to understand it.

In the below graphic you can see the recommended path to certification.

Path to certification diagram (image by Xamarin University)
Path to certification diagram (image by Xamarin University)

Per track you can see what classes are available, which you have already completed and which is recommended next. The latter can also be found at more places along with the information on which times the class is available next and the ability to sign up for that specific class right away!

Underneath you can see an example of that. Here are the Self-Guided Learning classes again, they are very great! They can serve as a replacement session for an actual instructor session. So if you cannot find a suitable time or feel confident enough about a certain subject you can check out the Self-Guided class and go through it in your own time at your own pace. And the awesome thing is that it also counts as a completed class! So with this you can even achieve your goal faster!

Xamarin University Tracks
Xamarin University Tracks

Basically all pages in here are a different view for the same thing; what classes are upcoming? What classes have you planned/done already? How far along are you on a certain track? Etc. That last bit is a nice one, they’ve added some gamification to it. And damn it, I am a sucker for it, wanting to fill up all those progress bars.

That rotten nifty gamification
That rotten nifty gamification

This gives you a direct overview of how far along you are on all subjects. Of course there is no restrictions on how often you follow one class and each class has a recorded session as well if things went a little too fast for you. Note: watching (back) a video doesn’t count as attending the class.

Ok great, but how about that certification?

Woops, sorry, lost track there. So, certification!

As I have mentioned; there are 15 classes you need to follow before having a try at the certification exam. This should take you about 4 months if you’re a starting Xamarin developer. If you already have some experience, no worries, there are a couple of things you can do to get to the exam faster. First there is the Introductory Assessment Exam. This is a test you can take to prove that you already have (basic) knowledge of Xamarin. If you can pass the test with 80% or more then you can skip 7 (seven!) of the 15 classes, so you’re halfway there already. The test consists of 50 questions for which you have 60 minutes.

It certainly is doable, but there are some tricky questions in there, so pay attention! Even more so because you only get one shot. If you don’t make it, no worries, but you’ll have to attend to those 7 classes in order to qualify.

Now the classes are awesome! The instructors are even better. They take all the time to explain everything to you, have a lot of patience and all have the own trademark. One asks you where in the world all attendees are from, the other goes through the list and giving everyone the chance to introduce themselves shortly. Classes tend to be about 20-30 persons which also has a bit of a downside.
When all mics are unmuted and you are responsible for your own muting, people sometimes forget or people simply just don’t know it because they come in later. So you hear a lot of noise and ‘oops, let me mute the mic of someone coming in’. It isn’t a total disaster, but could be a bit disruptive. He total upside from that is that you can use you mic! And ask everything you like! Which rhymes.

With each class comes some materials which usually consists of some code to get you started and a recap of everything that is handled in class.

GoToTraining class session
GoToTraining class session


So you’re all excited now and want to check it out for yourself? You can start a trial right here. And you know what’s awesome? All courses you follow here, including the self-guided once, count towards certification already! So try it, and if you like it, sign up when you are ready and pick up right where you left off not losing any time! The rewards in knowledge is great, but check out these these bad boys below. That makes it all worth it right?!

Xamarin Certified Developer glass plaques
Xamarin Certified Developer glass plaques
July 13, 2016 6:24 GMT

Creating a Five-Star Search Experience with Azure Search

Search is a feature that can make or break a mobile app, but it can be incredibly difficult to get right. Often, the likelihood that a user continues to use your app depends on the quality of the search experience; if Yelp didn’t help me find restaurants or Amazon didn’t display the products I was looking for, I’d likely abandon that service.

There are so many options for developers looking to implement search solutions into their apps. Some of us may opt for using LINQ and the Entity Framework to query a table, or the more adventurous of us may opt to create an instance of Elastic Search, which requires a lot of work and knowledge to set up and maintain. For my app Beer Drinkin, I’m using Microsoft’s Azure Search service, since it has proved to be easy to configure and requires zero maintenance. In this blog post, you’ll learn how to implement intelligent search with Azure Search into a mobile app.

Dealing with spelling mistakessearchresults

One of the main reasons that I’ve opted to use Azure Search is to resolve off-by-one-letter spelling mistakes, which yield no results. One alternative way I considered to address spelling mistakes was to utilize a spell checking service, like WebSpellChecker.net. The issue with a service such as WebSpellChecker is that it has no context in which to make corrections. It struggled with product names like Duvel, often offering to correct my spelling to Duvet, which would be incorrect and yield no result.

One popular way to minimize spelling mistakes is to provide a list of suggestions as the user types in a search query. You’re probably familiar with this in search engines like Google and Bing. This approach to searching is intuitive for users and significantly reduces the number of spelling mistakes. This is built into Azure Search with an easy to use API for consuming the predictions.

Enter Azure Search

Azure Search aims to remove the complexity of providing advanced search functionality by offering a service that does the heavy lifting for implementing a modern and feature-rich search solution. Microsoft handles all of the infrastructure required to scale as it gains more users and indexes more data. Not to mention that Azure Search supports 50 languages, which use technologies from multiple teams within Microsoft (such as Office and Bing). What this equates to is that Azure Search actually understands the intent of a search for intuitive results; it doesn’t just evaluate the result based on the characters typed.

Some of my favorite features include:

  • Fuzzy Search: Find strings that match a pattern approximately.
  • Proximity Search: Geospatial queries allow you to find search targets within a certain distance of a particular point.
  • Term Boosting: Boosting allows you to promote results based on rules you create. One example might be to boost old stock or discounted items.

Getting Started

The first step towards adding intelligent search to your mobile apps is to provision an instance of Azure Search within the Azure Portal. Because my index already contains over 60,000 beers, I opted for the basic plan. The basic plan comes with more power through the use of dedicated resources, and I’m able to store 2GB of data and one million documents. I can also scale out to three units, which provides me with plenty of room to grow.

Creating an Index

Before I could take advantage of Azure Search, I needed to upload my data to be indexed. Fortunately, with the .NET SDK the Azure Search team provides, it’s exceptionally easy to interact with the service. Using the .NET library I wrote to interact with the BreweryDB REST API, I was able to iterate quickly through each page of beer results and upload them in blocks to the search service.

Screen Shot 2016-01-04 at 10.18.02.png

Uploading Documents

You can see how easy it is to import documents into Azure Search, as I did below with the BreweryDB.NET library.

Parallel.For(1, totalPageCount, new ParallelOptions {MaxDegreeOfParallelism = 25}, index =&amp;amp;amp;amp;amp;amp;amp;amp;gt;
    var response = client.Beers.GetAll(index).Result;
    var beersToAdd = new List();
    foreach (var beer in response.Data)
        var indexedBeer = new IndexedBeer
            Id = beer.Id,
            Name = beer.Name,
            Description = beer.Description,
            BreweryDbId = beer.Id,
            BreweryId = beer?.Breweries?.FirstOrDefault()?.Id,
            BreweryName = beer?.Breweries?.FirstOrDefault()?.Name,
            AvailableId = beer.AvailableId.ToString(),
            GlassId = beer.GlasswareId.ToString(),
            Abv = beer.Abv
         if (beer.Labels != null)
            indexedBeer.Images = new[] {beer.Labels.Icon, beer.Labels.Medium, beer.Labels.Large};
    Console.Write( $"\rAdded {beersToAdd.Count} beers to Index | Page {processedPageCount} of {totalPageCount}");

Other Data Import Methods

Azure Search also supports the ability to index data stored in Azure SQL or DocumentDB, which enables me to point a crawler to my SQL table, removing the need to manually manage the index yourself. There are a few reasons you may not want to use a crawler. The best reason for not using a crawler is that it introduces the possibility of a delay between your database changing and your search index reflecting the changes. The crawler will only crawl on a schedule, which results in an out-of-date index.

If you opt for the self-managed approach, you can add, remove, and edit your indexed documents yourself as the changes happen in your back end. This provides you with live search results, since you know the data is always up-to-date. Using the crawler is an excellent way to get started with search and quickly get some data in place, but I wouldn’t consider it a good strategy for long-term use.


Before we can use suggestions, we’ll need to ensure that we’ve created a suggester within Azure.

Screen Shot 2016-01-04 at 10.27.15.png

In the current service release, there is support for limited index schema updates. Any schema updates that would require reindexing, such as changing field types, are not currently supported. Although existing fields cannot be modified or deleted, new fields can be added to an existing index at any time.

If you haven’t checked the suggester checkbox at the time of creating a field, then you’ll need to create a secondary field, because Azure Search doesn’t currently support editing the fields. The Azure Search team recommends that you create new fields if you require a change in functionality.

The simplest way to get suggestions would be to use the following API.

var response = await indexClient.Documents.SuggestAsync(searchBar.Text, "nameSuggester");
foreach(var r in response)

Having fun with the suggestion API

The API suggestion provides properties for enabling fuzzing matching and hit highlighting. Let’s see how we might enable that functionality within our app.

var suggestParameters = new SuggestParameters();
suggestParameters.UseFuzzyMatching = true;
suggestParameters.Top = 25;
suggestParameters.HighlightPreTag = "[";
suggestParameters.HighlightPostTag = "]";
suggestParameters.MinimumCoverage = 100;

What do the properties do?

UseFuzzyMatching: The query will find suggestions even if there’s a substituted or missing character in the search text. While this provides a better search experience, it comes at the cost of slower operations and consumes more resources.

Top: The number of suggestions to retrieve. It must be a number between 1 and 100, with its default set to 5.

HightlightPreTag: Gets or sets the tag that is prepended to hit highlights. It MUST be set with a post tag.

HightlightPostTag: Gets or sets the tag that is prepended to hit highlights. It MUST be set with a pre tag.

MinimumCoverage: Represents the percentage of the index that must be covered by a suggestion query in order for the query to be reported a success. The default is 80%.

How do the results look?



The Search API itself is even easier (assuming we don’t use filtering, which is a topic for another day).

var searchParameters = new SearchParameters() { SearchMode = SearchMode.All };
indexClient.Documents.SearchAsync(searchBar.Text, searchParameters);

Getting Started

The easiest way to get started with Azure Search is to create an instance from the Azure Portal and then use my previous blog post to implement search suggestions in your own apps. You can also find plenty of videos on Youtube of the Azure Search team discussing the service and a full iOS sample on my Github.

This blog post was originally published on my personal blog and has been updated to reflect changes in Azure Search.

The post Creating a Five-Star Search Experience with Azure Search appeared first on Xamarin Blog.

July 12, 2016 6:45 GMT

RecyclerView: Highly Optimized Collections for Android Apps

I’ve spent hours of development time trying to optimize Android’s ListView to make scrolling through items smooth, followed by similar amounts of time attempting to optimize and configure Android’s GridView if I wanted to display more than one column of data at a time. These days of struggling to remember the correct pattern (and copy and pasting code from adapter to adapter) are now over, thanks to the introduction of Android’s RecyclerView. The RecyclerView has been around for a while now, having been introduced in Support Library v7 as a NuGet package, so you can use it in all of the applications you’re currently developing. Today, we’ll take a look at integrating the RecyclerView into an app with some similar paradigms of the ListView.

RecyclerView Recycling

Adding the NuGet

The first step is to add the NuGet package to your Android project. This will give you direct access to the widget in code and for Android XML.


Integrate RecyclerView Widget

Just like any other Android widget, you can simply add the RecyclerView directly into your existing Android XML or even replace your ListView with a RecyclerView:


Item Layout

For this app, I’m displaying a list of images that are inside of a CardView to add a nice drop shadow:


Bringing It All Together

With the main layout and item layout all set up, it’s time to bring them together and start displaying items. The RecyclerView has three required classes that need to be implemented for each:


  • RecyclerView.ViewHolder: Caches references to the views in your item layout file so that resource lookups are not repeated unnecessarily.
  • RecyclerView.Adapter: Provides a binding from your app’s data set (which is specific to your app) to item views that are displayed within the RecyclerView.
  • RecyclerView.LayoutManager: Positions items within the RecyclerView.

RecyclerView ViewHolder & Adapter

The RecyclerView ViewHolder seem familiar if you have optimized ListViews in the past. This class must be a subclass of RecyclerView.ViewHolder and has one job, which is to cache all views by finding them by their ID.

public class ImageAdapterViewHolder : RecyclerView.ViewHolder
        public ImageView Image { get; private set; }
        public TextView Caption { get; private set; }
        public ImageAdapterViewHolder(View itemView) : base(itemView)
            Image = itemView.FindViewById(Resource.Id.imageView);
            Caption = itemView.FindViewById(Resource.Id.textView);

This ViewHolder is used in the main adapter, which actually inflates the view and sets the properties on each widget. It must inherit from RecyclerView.Adapter and then implement three methods to handle layout inflating, binding, and the count of items that are to be displayed.

class ImageAdapter : RecyclerView.Adapter
        Image[] images;
        Activity activity;
        public ImageAdapter(Activity activity, Image[] images)
            this.images = images;
            this.activity = activity;
        // Create new views (invoked by the layout manager)
        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
            //Setup and inflate your layout here
            var id = Resource.Layout.item;
            var itemView = LayoutInflater.From(parent.Context).Inflate(id, parent, false);
            return new ImageAdapterViewHolder(itemView);
        // Replace the contents of a view (invoked by the layout manager)
        public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
            var item = images[position];
            // Replace the contents of the view with that element
            var holder = viewHolder as ImageAdapterViewHolder;
            holder.Caption.Text = item.Title;
        public override int ItemCount => images.Count;

With the adapter in place, it’s time to tie it together with the RecyclerView in the Main Activity:

[Activity(Label = "Image Search", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : AppCompatActivity
        RecyclerView recyclerView;
        RecyclerView.LayoutManager layoutManager;
        ImageAdapter adapter;
        Image[] images;
        protected override int LayoutResource
            get { return Resource.Layout.main; }
        int count = 1;
        protected override void OnCreate(Bundle bundle)
            //Create Images here
            images = new [] { new Image { Caption = "Baboon", Image = "http://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Portrait_Of_A_Baboon.jpg/314px-Portrait_Of_A_Baboon.jpg" } };
            //Setup RecyclerView
            adapter = new ImageAdapter(this, images);
            recyclerView = FindViewById(Resource.Id.recyclerView);

Managing the Layout

The last part of the RecyclerView is to set the LayoutManager. This allows complete customization of how items in the list are laid out. Built into the RecylerView library are a few default layout managers to get started, including the LinearLayoutManager and the GridLayoutManager.


This manager will layout items either horizontally or vertically:

layoutManager = new LinearLayoutManager(this, LinearLayoutManager.Vertical, false);



This manager allows a set number of columns in a list, which is great for displaying multiple images in a list:

layoutManager = new GridLayoutManager(this, 2);


The beautiful part of the LayoutManager is that you can change them at any time for customization depending on the type of device the app is running on.

Learn More

This is just the beginning of what’s possible with the RecyclerView and its immense power. Be sure to read through our complete documentation on how to customize the item decoration, add click handlers, and a lot more. You can find the source code for this example on my GitHub page.

The post RecyclerView: Highly Optimized Collections for Android Apps appeared first on Xamarin Blog.

July 12, 2016 3:35 GMT

Yet Another Podcast #156 – MVVM Light with Laurent Bugnion


Laurent works as Senior Director for IdentityMine, one of the leading companies (and mvvmlightGold Partner) for Microsoft technologies such as Windows Presentation Foundation, Xamarin, Windows Store, Windows Phone, XBOX and generally User Experience. He is based in Zurich Switzerland.

Laurent writes for MSDN magazine and other publications, codes in Windows, WPF, Xamarin (iOS and Android), ASP.NET and his blog is on blog.galasoft.ch. He is a frequent speaker at conferences such as Microsoft MIX, TechEd, VSLive, TechDays and many other international events. 2016 is his 10th year as aMicrosoft Most Valuable Professional (Windows Application Development), his third year as a Microsoft Regional Director and his second year as a Xamarin Most Valuable Professional. He is the author of the well-known open source framework MVVM Light for Windows, WPF, Xamarin, and of the popular Pluralsight reference course about MVVM Light.






July 09, 2016 11:00 GMT

.NET Core Test Runner Support in Xamarin Studio

The latest version of the .NET Core addin for Xamarin Studio and MonoDevelop now supports .NET Core Test Runners.

.NET Core Test Runner in Xamarin Studio

Xamarin Studio uses the .NET Core test communication protocol to support .NET Core test runners. This protocol provides a way to discover and run the unit tests provided by a .NET Core test runner.

When Xamarin Studio finds a testRunner in the project.json file it will attempt to discover the unit tests for that project.

    "version": "1.1.0-*",

    "testRunner": "nunit",

    "dependencies": {,
        "NUnit": "3.4.0",
        "dotnet-test-nunit": "3.4.0-beta-1"

    "frameworks": {
        "netcoreapp1.0": {
            "imports": [
            "dependencies": {
                "Microsoft.NETCore.App": {
                    "version": "1.0.0-*",
                    "type": "platform"

The discovered tests are then shown in the Unit Tests window.

Discovered NET Core unit tests in Unit Tests window

After building the project the Unit Tests window will discover any new tests that have been added.

Tests can be run by clicking Run All or by right clicking a test in the Unit Tests window and selecting Run Test.

Run NET Core unit tests in Unit Tests window

The test results are shown in the Test Results window.

.NET Core test results  in Test Results window

Console output from the test runner is shown in the Application Output window.

.NET Core Test Runner in Xamarin Studio

Debugging the unit tests is not yet supported.

xUnit and NUnit provide .NET Core test runners and both of these are supported in Xamarin Studio. More information can be found in existing tutorials on how to use these test runners:

July 08, 2016 12:00 GMT

Build Xamarin.Forms from Source

One thing I’ve found not much information out there on is how to build your own copy of Xamarin.Forms and use it in your application. With just a little effort I was able to setup Visual Studio Team Services to build my fork of Xamarin.Forms and deploy a NuGet package to our private feed on MyGet. I think people out there are probably interested in setting this up, especially if you have a project pushing Xamarin.Forms to its limits.
July 07, 2016 7:43 GMT

Streaming a Web video to AppleTV with Xamarin

If you have the URL of a streaming video, it’s easy to display on an AppleTV, even though tvOS does not have a UIWebView (which would make it really easy). You have to use some AVFoundation code, such as:

var src = NSUrl.FromString("https://somevideo");
var asset = AVAsset.FromUrl(src);
var playerItem = new AVPlayerItem(asset);
var player = new AVPlayer (playerItem);
var playerLayer = AVPlayerLayer.FromPlayer (player);
//Might want to modify this so that it's the same size as the source video
var frame = new CGRect (0, 0, this.View.Frame.Width, this.View.Frame.Height);
playerLayer.Frame = frame;
this.View.Layer.AddSublayer (playerLayer);
player.Play ();

Note: This won’t work with normal YouTube page URLs since the YouTube stream URLs are not directly accessible.

July 06, 2016 5:52 GMT

Continuous - C# and F# IDE for the iPad

Over the past six months I have been working on a new .NET IDE for the iPad, and today I am very pleased to release it on the App Store.

Continuous IDE on an iPad

Continuous gives you the power of a traditional desktop .NET IDE - full C# 6 and F# 4 language support with semantic highlighting and code completion - while also featuring live code execution so you don’t have to wait around for code to compile and run. Continuous works completely offline so you get super fast compiles and your code is secure.

Continuous gives you access to all of .NET’s standard library, F#’s core library, all of Xamarin’s iOS binding, and Xamarin.Forms. Access to all of these libraries means you won’t be constrained by Continuous - you can write code exactly as you’re used to.

Real Work, on the iPad

I love the iPad but was still stuck having to lug around my laptop if I ever wanted to do “real work”. Real work, in my world, means programming. There are indeed other IDEs for the iPad: there is the powerful Pythonista app and the brilliant Codea app. But neither of those apps was able to help me in my job: writing iOS apps in C# and F#. I couldn’t use my favorite languages on my favorite device and that unfortunately relegated my iPad to a play thing.

That realization produced this tweet last December:

Well it took me a bit of time, but I finally have it: a .NET IDE on the iPad (and phone too!).

But it’s not “just an IDE”. I didn’t want it to simply be sufficient - I wanted it to be great. I also thought it was a nice time to push the state of the art in .NET IDEs a tad.

For ages compiled languages like C# and F# have forced a sequential development loop on programmers: the Code-Compile-Run-Test loop. We code something up, wait for it to compile, then wait for it to deploy and run, then we get to test it.

I hate waiting for compilation and deployment so I designed Continuous to minimize those steps. It does this by eagerly compiling your code - never waiting for you to tell it when to start. It runs your code as soon as those compiles complete successfully and displays the results of that execution right next to your code. Now you can focus on the code and the results of that code instead of being distracted by all the silly machinery of a compiler and IDE.

The benefits of making compilation and execution fast have surprised me. My iPad has become my favorite place to write apps now.

  • The UI is visualized right next to the code that is building it.
  • I am no longer constrained by designers with their static view of the world - the UI objects in Continuous are live and interactive.
  • I can use real code files but still visualize objects out of them as if they were scripts.
  • I can focus on building one screen of my app at a time and see the results without having to navigate from the first screen to see the screen I’m working on over and over.

I could argue that I’m a more efficient programmer thanks to these changes. Perhaps I am more productive. But the truth is, I’m just happier using Continuous. I play with GUIs more now, trying new ideas and tweaking things left and right. It’s quite liberating and plain old fun to get nearly instant feedback on your work.

I hope you find these features as exciting as I do. Please visit the website if you want more details on them, or throw caution to the wind and buy Continuous on the App Store now to see them first-hand.

Standing on the shoulders of giants

Continuous wouldn’t be possible if it wasn’t for .NET’s great open source ecosystem. Continuous uses Roslyn for compiling C# and FSharp.Compiler.Service for compiling F#. Continuous also relies heavily on Cecil (what problem can’t be solved with Cecil?) Also, Xamarin.Forms could only be included thanks to Xamarin open sourcing it.

And of course, none of this would be possible without mono and Xamarin.


I wrote Continuous in F# using Xamarin Studio. The code is more functional than object oriented and uses a redux style architecture. I don’t think I could have built such a large app with its sophisticated requirements without F# at my side. Three years ago I wasn’t sure how to write GUI apps in a functional language, now I question why I haven’t always done things this way.

July 05, 2016 2:28 GMT

Spicing up your Xamarin (Forms/iOS) TabBar

One of the most popular navigation patterns on all platforms is by making use of the TabBar. Xamarin.Forms already acknowledged this by incorporating the TabbedPage in their default control set. While the tabs are platform independent – besides from the look on the specific platform – I want to talk a little bit about the iOS part specifically.

When I first started out with Xamarin and Forms I just put in the TabbedPage, specify some icons and be done with it. But looking at other iOS apps, mine always seemed to be odd. Soon I figured out why; on iOS a selected tab has a selected icon which is typically a filled icon. Let’s have a look.

TabBar Icons
TabBar Icons

This is how a TabBar icon and selected TabBar icon looks like in default Xamarin.Forms with iOS. If we compare this to the TabBar in the iOS App Store app we notice the difference immediately. It has filled icons! So how can we achieve this in our app?

AppStore TabBar icons
AppStore TabBar icons

Diving into this I quickly came across some Apple documentation which told me that it can be done out of the box on iOS with the selectionIndicatorImage property. So Xamarin Forms probably lacks the possibility due to the fact that only the most multi-platform features are implemented. But no worries! This is where Custom Renderers come in very handy!

So lets jump right in, go over to the iOS project, create a custom renderer – you remember how, right? – and put this into it.

using System;
using iOSTabBarSample.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;

[assembly: ExportRenderer (typeof (TabbedPage), typeof (TabBarRenderer))]

namespace iOSTabBarSample.iOS
    public class TabBarRenderer : TabbedRenderer
        private bool _initialized;

        public override void ViewWillAppear (bool animated)
            if (!_initialized) {
                if (TabBar?.Items == null)

                var tabs = Element as TabbedPage;

                if (tabs != null) {
                    for (int i = 0; i < TabBar.Items.Length; i++) {
                        UpdateItem (TabBar.Items [i], tabs.Children [i].Icon, tabs.Children [i].StyleId);

                _initialized = true;

            base.ViewWillAppear (animated);

        private void UpdateItem (UITabBarItem item, string icon, string badgeValue)
            if (item == null)

            try {
                if (icon.EndsWith (".png"))
                    icon = icon.Replace (".png", "_selected.png");
                    icon += "_selected";

                item.SelectedImage = UIImage.FromBundle (icon);
                item.SelectedImage.AccessibilityIdentifier = icon;
            } catch (Exception ex) {
                Console.WriteLine ("Unable to set selected icon: " + ex);

So what happens here?

In the ViewWillAppear method we determine if there are any tab items to process. I’ve also included a boolean to make sure it only runs the first time the page is shown. If the SelectedImage is set, we don’t need to touch it again.

Then we are going to take those tab items and run them through the UpdateItem method we have created. Inside that method you see that first thing is to check how our icons are named. In Xamarin.Forms you can skip the extension and the images are correctly found on each platform. If you did add the extension for some reason, let’s just get that checked.

But either way, we append ‘_selected’ to it and set the SelectedImage property to that icon. And that’s it!
Of course, if you want another naming convention, feel free. Also, if you want to be completely free to give in a different name altogether, you might want to look at inheriting the Page and add a SelectedIcon property to it or something. Be creative!

If we run the app now, we directly see the effects.

Filled TabBar icons
Filled TabBar icons

Wow! Awesome! That’s what I’m talking about!

Now while we are at it, you can give it your own color as well. This can be done with something called the TintColor. This is useable on multiple types of controls, but is also used for coloring the icons and text in the TabBar.

To do this just add this one line in your AppDelegate.

[Register ("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
            global::Xamarin.Forms.Forms.Init ();

            UITabBar.Appearance.TintColor = Color.Red.ToUIColor ();

            LoadApplication (new App ());

            return base.FinishedLaunching (app, options);

Check out the line starting with UITabBar. Now of course you can set any color there.

When we run it now it looks nice and red!

Red and selected TabBar icons
Red and selected TabBar icons

Now your Xamarin Forms iOS app wil look a lot more like an actual iOS app!

The code for this sample project can be found on GitHub right here. Enjoy!

July 05, 2016 11:40 GMT

Add custom tiles to map in Xamarin Forms

If we want to use other maps than the platforms default in our apps we need to provide tiles to the map view. To do that we need to create a custom renderer per platform.

In iOS we need to create an url template that contains {x}, {y} and {z}. Those be replaced with values from the map engine.

protected override void OnElementChanged(ElementChangedEventArgs<View> e)
    if(e.NewElement != null)
        var map = (MKMapView)Control;
        var urlTemplate = "https://urltomaptiles/{x}/{y}/{z}";
        var tileOverlay = new MKTileOverlay(urlTemplate);
        map.OverlayRenderer = OverlayRenderer;
private MKOverlayRenderer RenderOverlay(MKMapView mapView, IMKOverlay overlay)
    var tileOverlay = overlay as MKTileOverlay;
    if(tileOverlay != null)
         return new MKTileOverlayRenderer(tileOverlay);
    return new MKOverlayRenderer(overlay);

If we are getting tiles from a service that not supporting the url format with x-,y- and z value we can customize the url. To do that we need to subclass MKTileOverlay and override the URLForTilePath method. In that method we will write the code that created the url. I recommend to create a helper class for that so we can reuse it on the other platforms.

public class CustomTileOverlay : MKTileOverlay
     public override void LoadTileAtPath(MKTileOverlayPath path, MKTileOverlayLoadTileCompletionHandler result)
         base.LoadTileAtPath(path, result);
     public override NSUrl URLForTilePath(MKTileOverlayPath path)
         //Here we write the code for creating the url.
         var url = MapHelper.CreateTileUrl((int)path.X, (int)path.Y, (int)path.Z);
         return new NSUrl(url);

Instead of creating a MKTileOverlay we will create a CustomTileOverlay and add it to the map.

map.AddOverlay(new CustomTileOverlay());

Except to subclass MapRenderer we also need to implement the IOnMapReadyCallback interface. The method OnMapReady will handle when the GoogleMap object is ready so we can work with it. But first we need to request the GoogleMap object in the override of the OnElementChanged method.

public class ExtendedMapRenderer : MapRenderer, IOnMapReadyCallback
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        if(e.NewElement != null)
    public void OnMapReady(GoogleMap googleMap)
        var options = new TileOverlayOptions();
        options.InvokeTileProvider(new CustomTileProvider());

In Android we always need to create an own tile provider.

public class CustomTileProvider : UrlTileProvider
    public CustomTileProvider() : base(256,256) {}
    public override URL GetTileUrl(int x, int y, int zoom)
        //Here we write the code for creating the url.
        var url = MapHelper.CreateTileUrl(x, y, zoom);
        return new URL(url);

UWP (Windows 10)
As in iOS, UWP using an url that contains {x},{y} and {z} that will be replaced by the map engine.

protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
    if (e.NewElement != null)
        map = Control as MapControl;
        HttpMapTileDataSource dataSource = new HttpMapTileDataSource("https://urltomaptiles/{x}/{y}/{z}");      
        MapTileSource tileSource = new MapTileSource(dataSource);

If we want to modify the url we using the UriRequested event on HttpMapTileDataSource.

HttpMapTileDataSource dataSource = new HttpMapTileDataSource();
dataSource.UriRequested += DataSource_UriRequested;

The code for modifying the url is placed in the event handler.

private void DataSource_UriRequested(HttpMapTileDataSource sender, MapTileUriRequestedEventArgs args)
    var deferral = args.Request.GetDeferral();
    //Here we write the code for creating the url.
    var url = MapHelper.CreateTileUrl(args.X, args.Y, args.ZoomLevel);
    args.Request.Uri = new Uri(url);
July 03, 2016 2:40 GMT

Xamarin.Forms: Creating a sliding drawer with behaviors, messages and MVVM Light

Sliding Drawers have become a popular, almost required form of navigation in phone applications.  There are libraries that will do this for you, but you can use Xamarin.Forms to create what you want without too much effort.  Okay, with quite a bit of effort, but it is like following a recipe.  Ok, a complicated recipe.  So fasten your seatbelts…

How the Pieces Fit Together Sliding Drawers

We’re going to have two kinds of pages:

  • Normal content pages
  • Master and Detail pages

We begin, as usual by creating our MVVM folders, and one more for Behaviors.  Let’s create four pages that we’ll navigate among.  We can just name them Page 1, Page 2, Page 3 and Page 4, though in a real application you’ll no doubt give them more meaningful names.

Now it’s time to create the navigation, based on your Master/Details pages.  For this we need to declare two pages:

  • Our Root page: type MasterDetailPage
  • Our Drawer page: type Content Page

These two work together to have the drawer page slide over the current page and offer navigation as shown above.

Root Page

The RootPage has virtually no XAML,

<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
                  Title="Sliding Drawer">

Notice the title– that is required.

The fun is in the code behind (yes, I know, we really don’t like putting code in code-behind),

We start with the constructor,

    public RootPage( )
      InitializeComponent( );
      var drawerPage = new Drawer( );
                 this, ( m ) => NavigateToNewPage( m ) );
      Master = drawerPage;
      Detail = new NavigationPage( new Page1( ) );


There are a few things to notice here.  First, the call to Messenger.  This draws on MVVM Light, which you easily obtain form NuGet.

The second is that we’re setting the built-in Master property to the drawer page and the built-in Detail property to page 1.  This gets us started.  In App.cs we set the MainPage to this RootPage,

    public App( )
      InitializeComponent( );

      MainPage = new RootPage( );

That sets up our basic navigation pattern.

The Drawer

Let’s turn to the DrawerPage.  Here is the XAML for the drawer.  It is based on a ListView,

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             Title="Sliding Drawer"
  <StackLayout BackgroundColor="#EFEFEF">
    <ContentView Padding="20,20,0,0" BackgroundColor="#2196F3">
        <StackLayout Orientation="Horizontal">
          <Label Text="Liberty" TextColor="#FFFFFF" 
    <ListView x:Name="ListViewMenu" 
             ItemsSource="{Binding MenuItems}" >
            Command="{Binding MenuItemSelectedCommand}" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <RowDefinition Height="40" />
              <Label Text="{Binding Title}" Grid.Row="0" 
                 VerticalTextAlignment="Center" />

That’s a fair amount of XAML but the only tricky part is the ListView’s Behaviors section. This is where we create our first behavior,  Our goal is to turn the event ItemSelected into a command we can handle in the code behind.

Event To Command Behavior

Much has already been written about EventsToCommands, so I’ll just skim over the code.  We begin by creating the base class,

 public class BehaviorBase : Behavior where T : BindableObject
    public T AssociatedObject { get; private set; }

This derives from the built-in Behavior class and is, as you can see, generic.

Thee are four key methods. First is the method called when the behavior is attached to the target element (the AssociatedObject)

  protected override void OnAttachedTo( T bindable )
      base.OnAttachedTo( bindable );
      AssociatedObject = bindable;

      if (bindable.BindingContext != null)
        BindingContext = bindable.BindingContext;

      bindable.BindingContextChanged += OnBindingContextChanged;

Next, we handle OnDetachingFrom, an often overlooked method which helps prevent memory leaks,

   protected override void OnDetachingFrom( T bindable )
      base.OnDetachingFrom( bindable );
      bindable.BindingContextChanged -= OnBindingContextChanged;
      AssociatedObject = null;

Finally, we handle the OnBindingContextChanged event by calling hte overridden OnBindingContextchanged

    void OnBindingContextChanged( object sender, EventArgs e )
      OnBindingContextChanged( );

    protected override void OnBindingContextChanged( )
      base.OnBindingContextChanged( );
      BindingContext = AssociatedObject.BindingContext;

The EventToCommandBehavor

We now turn to the derived class, which of course derives from the base class we just created,

  public class EventToCommandBehavior : BehaviorBase
    Delegate eventHandler;

Let’s start with the four properties,

    public static readonly BindableProperty EventNameProperty = 
      BindableProperty.Create( "EventName", typeof( string ), 
        typeof( EventToCommandBehavior ), null, 
        propertyChanged: OnEventNameChanged );

    public static readonly BindableProperty CommandProperty = 
      BindableProperty.Create( "Command", typeof( ICommand ), 
        typeof( EventToCommandBehavior ), null );

    public static readonly BindableProperty 
               CommandParameterProperty = 
      BindableProperty.Create( "CommandParameter", 
      typeof( object ),
      typeof( EventToCommandBehavior ), null );

    public static readonly BindableProperty 
    InputConverterProperty = 
      BindableProperty.Create( "Converter",
        typeof( IValueConverter ),
        typeof( EventToCommandBehavior ), null );

For each of these we need a private pair of GetValue and SetValue commands,

   public string EventName
      get { return (string)GetValue( EventNameProperty ); }
      set { SetValue( EventNameProperty, value ); }

    public ICommand Command
      get { return (ICommand)GetValue( CommandProperty ); }
      set { SetValue( CommandProperty, value ); }

    public object CommandParameter
      get { return GetValue( CommandParameterProperty ); }
      set { SetValue( CommandParameterProperty, value ); }

    public IValueConverter Converter
      get { return (IValueConverter)GetValue( 
                InputConverterProperty ); }
      set { SetValue( InputConverterProperty, value ); }

Next, because these are attached properties, we need the associated methods. Let’s start with OnAttachedTo and OnDetachingFrom,

 protected override void OnAttachedTo( 
           Xamarin.Forms.View bindable )
      base.OnAttachedTo( bindable );
      RegisterEvent( EventName );

    protected override void OnDetachingFrom( 
             Xamarin.Forms.View bindable )
      DeregisterEvent( EventName );
      base.OnDetachingFrom( bindable );

Now we need the ability to attach to and detach from an element,

   protected override void OnAttachedTo( 
            Xamarin.Forms.View bindable )
      base.OnAttachedTo( bindable );
      RegisterEvent( EventName );

    protected override void OnDetachingFrom(
              Xamarin.Forms.View bindable )
      DeregisterEvent( EventName );
      base.OnDetachingFrom( bindable );

Ok, now things get interesting. First is the code for when the event is registered,

   void RegisterEvent( string name )
      if (string.IsNullOrWhiteSpace( name ))

      EventInfo eventInfo = AssociatedObject.GetType( )
             .GetRuntimeEvent( name );
      if (eventInfo == null)
        throw new ArgumentException(  
             "$EventToCommandBehavior: Can't register the 
                  '{EventName}' event."  );
      MethodInfo methodInfo = typeof( EventToCommandBehavior )
            .GetTypeInfo( ).GetDeclaredMethod( "OnEvent" );
      eventHandler = methodInfo.CreateDelegate( 
            eventInfo.EventHandlerType, this );
      eventInfo.AddEventHandler( AssociatedObject, eventHandler );

Each attached oobject is associated with an object to which they are attaching. That is the AssociatedObject described above, and seen earlier in the base class.

Deregistering Events follows (and helps prevent memory leaks),

void DeregisterEvent( string name )
      if (string.IsNullOrWhiteSpace( name ))

      if (eventHandler == null)
      EventInfo eventInfo = AssociatedObject.GetType( )
              .GetRuntimeEvent( name );
      if (eventInfo == null)
        throw new ArgumentException( "$EventToCommandBehavior: 
            Can't de-register the '{EventName}' event." );
           AssociatedObject, eventHandler );
      eventHandler = null;

We now turn to event handling,

    void OnEvent( object sender, object eventArgs )
      if (Command == null)

      object resolvedParameter;

      if (CommandParameter != null)
        resolvedParameter = CommandParameter;
      else if (Converter != null)
        resolvedParameter = Converter.Convert( 
                 eventArgs, typeof( object ), null, null );
      else if (eventArgs is SelectedItemChangedEventArgs)
        resolvedParameter = 
        resolvedParameter = eventArgs;

      if (Command.CanExecute( resolvedParameter ))
        Command.Execute( resolvedParameter );

And finally, we need OnEventNameChanged,

  static void OnEventNameChanged( 
             BindableObject bindable, 
             object oldValue, 
             object newValue )
      var behavior = (EventToCommandBehavior)bindable;
      if (behavior.AssociatedObject == null)

      string oldEventName = (string)oldValue;
      string newEventName = (string)newValue;

      behavior.DeregisterEvent( oldEventName );
      behavior.RegisterEvent( newEventName );

Finishing up with drawer, we turn to the code behind where we simply create and set the ViewModel, and set it as the BindingContext,

 public partial class Drawer : ContentPage
    private DrawerViewModel vm;
    public Drawer( )
      InitializeComponent( );
      vm = new DrawerViewModel();
      BindingContext = vm;

The View Model – DrawerViewModel

DrawerViewModel inherits from MVVM Light’s ViewModelBase

We want to add MenuItems to our observable collection of MenuItem,  but first we need to declare our MenuItems class.  In the Model folder we declare that simple clasee,

  public class MenuItem
    public string Title { get; set; }
    public Type TargetType { get; set; }

Next, we declare the collection

  public ObservableCollection MenuItems { get; set; } = 
          new ObservableCollection( );

We return to the constructor where we create four MenuItem objects and add them to the collection,

   public DrawerViewModel( )
      MenuItems.Add( new Model.MenuItem( )
        Title = "Page 1",
        TargetType = typeof( Page1 )
      } );
      MenuItems.Add( new Model.MenuItem( )
        Title = "Page 2",
        TargetType = typeof( Page2 )
      } );
      MenuItems.Add( new Model.MenuItem( )
        Title = "Page 3",
        TargetType = typeof( Page3 )
      } );
      MenuItems.Add( new Model.MenuItem( )
        Title = "Page 4",
        TargetType = typeof( Page4 )
      } );


While we are here, let’s handle the menuItemSelectedCommand called in the ListView.  For this we use MVVM Light’s RelayCommand,

    private RelayCommand menuItemSelectedCommand;

    public RelayCommand MenuItemSelectedCommand
        return menuItemSelectedCommand ??
               (menuItemSelectedCommand =
                 new RelayCommand(
                   ( menuItem ) => Messenger.Default.Send( 
                        new DrawerItemMessage( 
                           menuItem.TargetType ) ) ));



Communication from the View Model back to the page requires the existenace of a DrawerItemMessage.  as seen above.  This is declared in the Model folder,

  public class DrawerItemMessage
    public DrawerItemMessage( Type pageType )
      NavigateTo = pageType;

    public Type NavigateTo { get; set; }



This blog post would not have been possible without the valuable assistance of Eric Glover. Eric is not only an expert in MVVM Light, but also one of the brightest and skilled  programmers I’ve had the pleasure to work with.

July 01, 2016 3:17 GMT

Unit testing with Xamarin.Forms' DependencyService

Xamarin.Forms ships with a built-in Service Locator, called DependencyService, which allows us to register and resolve dependencies. Typically, we use this to enable accessing and invoking platform specific logic in our shared code. The DependencyService is very convenient and easy to use, but it does come with a limitation. Because the DependencyService is part of the Xamarin.Forms framework, it expects that the framework has been initialized prior to using it. This presents a problem when we're trying to unit test some code that uses the DependencyService.

Consider a typical cross platform view model class :

public class MainViewModel  
    public string Data { get; set; }
    public void LoadData()
        var database = DependencyService.Get<ISQLite>();
        // Use the database

If we wanted to write a unit test for this, it might look like this :

public class TestMainViewModel  
    public void Setup()
        // Use the testable stub for unit tests
        DependencyService.Register<ISQLite>(new MyFakeSqliteImplementation());

    public void ViewModelShouldLoadData()
        var vm = new MainViewModel();
        Assert.AreNotEqual(string.Empty, vm.Data);

Unfortunately, if we try to access the DependencyService outside of an iOS/Android/Windows host project, we will receive an exception

You MUST call Xamarin.Forms.Init()

In our unit test, we haven't called Xamarin.Forms.Init() anywhere, and we can't call that method outside of a host. In order to properly unit test the application, we are going to have to make some architectural changes.

Solution #1

The first possible solution would be to move away from the Service Locator pattern completely, and instead architect our app using Dependency Injection. There are many benefits to Dependency Injection over Service Locators, but this usually comes down to developer preference. There are many DI containers that work with Xamarin and I encourgage you to try them out.

Solution #2

If we really want to continue using the Service Locator pattern, but we also want to unit test our code, we will have to abstract Xamarin.Forms' implementation of the pattern.

To begin with, we need to create a Service Locator interface in our shared code project. Notice that this simply provides a way for our shared code to request an object based on a generic key. There is no reference or dependency to Xamarin.Forms at all.

public interface IDependencyService  
    T Get<T>() where T : class;

Next, we will change our MainViewModel to take in an implementation of the IDependencyService as a parameter. There are now two constructors for the MainViewModel. In the normal case of running our app, we will instantiate and use a new DependencyServiceWrapper() object (see below), which will continue to use Xamarin.Forms' DependencyService object internally. The second constructor allows us to pass in any object that implements the IDependencyService interface, including mocking or stubbing it out for unit testing purposes.

public class MainViewModel  
    private readonly IDependencyService _dependencyService;

    public MainViewModel() : this(new DependencyServiceWrapper())

    public MainViewModel(IDependencyService dependencyService)
        _dependencyService = dependencyService;

    public string Data { get; set; }
    public void LoadData()
        var database = _dependencyService.Get<ISQLite>();
        // Use the database

The DependencyServiceWrapper class will simply delegate its calls to Xamarin.Forms' built-in DependencyService, giving us the same behavior as before while running the app on a host.

public class DependencyServiceWrapper : IDependencyService  
    public T Get<T> () where T : class
        // The wrapper will simply pass everything through to the real Xamarin.Forms DependencyService class when not unit testing
        return DependencyService.Get<T> ();

While unit testing, we can create a simple implementation of the interface to use. In this case, we're just going to use a Dictionary<Type, object> to store the implementations. Even though the IDependencyService interface only defined a Get() method, the stub implementation also provides a Register() method. Using the stub means that we never use the DependencyService class, and therefore never have to call Xamarin.Forms.Init() during a unit test.

public class DependencyServiceStub : IDependencyService  
    privet readonly Dictionary<Type, object> registeredServices = new Dictionary<Type, object>();

    public void Register<T>(object impl)
        this.registeredServices[typeof(T)] = impl;

    public T Get<T> () where T:class
        return (T)registeredServices[typeof(T)];

Finally, we can update our unit test to use the new DependencyServiceStub.

public class TestMainViewModel  
    IDependencyService _dependencyService;
    public void Setup()
        _dependencyService = new DependencyServiceStub ();
        // Use the testable stub for unit tests
        _dependencyService.Register<ISQLite>(new MyFakeSqliteImplementation());

    public void ViewModelShouldLoadData()
        var vm = new MainViewModel(_dependencyService);
        Assert.AreNotEqual(string.Empty, vm.Data);
July 01, 2016 8:45 GMT

Xamarin.Forms Behaviors: RotateAction

Previously, I demonstrated using the EventHandlerBehavior and ScaleAction classes to run a scaling animation when an event occurs. The Behaviors Library for Xamarin.Forms has the notion of behaviors and actions. A behavior is attached to a control and listens for something to happen, such as an event firing. When the “something” happens, it triggers one or more actions, such as invoking a method or command. Actions are invoked by behaviors and executed on a selected control.

In this blog post, I’ll demonstrate using the EventHandlerBehavior and RotateAction classes to run a rotation animation when an event occurs.

Rotating a VisualElement when an Event Fires

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. It requires you to set an EventName property to the event that you want the behavior to listen to, and an Actions property to one or more actions that should be executed in response to the event firing. Note that the Actions property of the EventHandlerBehavior instance is set indirectly by creating the RotateAction instance as a child of the EventHandlerBehavior instance.

The RotateAction class performs a rotation animation, and allows the following optional properties to be set:

  • TargetObject – an object that is the VisualElement on which to run the animation. If this value is omitted the object the behavior is attached to will be set as the target on which to run the animation.
  • FinalAngle – a double that specifies the angle of the Rotation property to animate to. If this value is omitted the default value of 0.0 is used.
  • Axis – a RotationAxis that specifies whether to rotate on the X, Y, or Z axis. If this value is omitted the default value of Z is used.
  • Duration – an int that represents the length of the animation in milliseconds. If this value is omitted the default value of 250ms is used.
  • EasingFunction – an EasingFunction that specifies any velocity changes in the animation. If this value is omitted the default value of the Linear easing function is used.
  • IsRelative – a boolean that specifies whether to perform relative scaling. If this value is omitted the default value of false will be used. Relative rotation obtains the current Rotation property value for the start of the animation, and then rotates from that value to the value plus the value defined by the FinalAngle property.
  • Await – a boolean that represents whether the animation should be awaited, or whether it should be allowed to complete in the background. If this value is omitted the default value of false will be used.

The following code example demonstrates using the EventHandlerBehavior and RotateAction classes to implement a compound animation that concurrently rotates an Image control on the X, Y, and Z axes:

<Image x:Name="image" Source="monkey.png" Opacity="0" VerticalOptions="CenterAndExpand" />
<Button Text="Run Animation">
<behaviors:EventHandlerBehavior EventName="Clicked">
<!-- Compound Animation -->
<behaviors:RotateAction TargetObject="{x:Reference image}"
="110520" />
<behaviors:RotateAction TargetObject="{x:Reference image}"
="X" />
<behaviors:RotateAction TargetObject="{x:Reference image}"
="Y" />

When the Button.Clicked event fires, three RotateAction instances are concurrently executed over 10 minutes (600000 milliseconds). Each RotateAction instance makes a different number of 360 degree rotations – 307 rotations on the Z axis (110520/360 = 307), 251 rotations on the X axis (90360/360 = 251), and 199 rotations on the Y axis (71640/360 = 199). These values are prime numbers, therefore ensuring that the rotations aren’t synchronized and hence won’t result in repetitive patterns.

The advantage of using the RotateAction is that it’s possible to invoke animations through XAML, rather than having to use C#. In addition, when combined with behaviors, a scaling animation can easily be invoked from XAML when a behavior occurs, such as an event firing, or when a piece of data changes.

The sample application that this code comes from can be downloaded from GitHub.


The RotateAction class allows rotation animations to be invoked through XAML when a behaviors occurs, such as an event firing, or when a piece of data changes.

June 30, 2016 8:08 GMT

Yet Another Podcast 155 – Humanitarian Toolbox with Bill Wagner

Bill Wagner is a Microsoft Senior Content Developer creating documents and learning htboxmaterials for developers learning the .net platform.  He is also the president and on the board of directors of the Humanitarian Toolbox.

Bill spoke with me about what the Humanitarian Toolbox is, and how developers can get involved in this tremendously important work.



June 30, 2016 2:17 GMT

App-to-Market: Show Me the Money

Url for the article: https://visualstudiomagazine.com/articles/2016/06/29/app-to-market-show-me-the-money.aspx

More on This Topic:

Now that you've moved your idea to prototype and developed an actual minimum viable product that you can give to customers for some feedback, you're almost ready to take the next step and make some valuable time and monetary investments in it. It's time to talk about funding: Where to get it, how to get it, and how to use it.

Before we talk about funding, though, a few things you should know about the investors you go after and what makes technology startups riskier for those investors.

June 30, 2016 10:25 GMT

Xamarin.Forms Behaviors: ScaleAction

Previously, I demonstrated using the EventHandlerBehavior and TranslateAction classes to run a translation animation when an event occurs. The Behaviors Library for Xamarin.Forms has the notion of behaviors and actions. A behavior is attached to a control and listens for something to happen, such as an event firing. When the “something” happens, it triggers one or more actions, such as invoking a method or command. Actions are invoked by behaviors and executed on a selected control.

In this blog post, I’ll demonstrate using the EventHandlerBehavior and ScaleAction classes to run a scaling animation when an event occurs.

Scaling a VisualElement when an Event Fires

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. It requires you to set an EventName property to the event that you want the behavior to listen to, and an Actions property to one or more actions that should be executed in response to the event firing. Note that the Actions property of the EventHandlerBehavior instance is set indirectly by creating the ScaleAction instance as a child of the EventHandlerBehavior instance.

The ScaleAction class performs a scaling animation, which expands or contracts a VisualElement when invoked, and allows the following optional properties to be set:

  • TargetObject – an object that is the VisualElement on which to run the animation. If this value is omitted the object the behavior is attached to will be set as the target on which to run the animation.
  • FinalScale – a double that specifies the value of the Scale property to animate to. If this value is omitted the default value of 1 is used.
  • Duration – an int that represents the length of the animation in milliseconds. If this value is omitted the default value of 250ms is used.
  • EasingFunction – an EasingFunction that specifies any velocity changes in the animation. If this value is omitted the default value of the Linear easing function is used.
  • IsRelative – a boolean that specifies whether to perform relative scaling. If this value is omitted the default value of false will be used. Relative scaling obtains the current Scale property value for the start of the animation, and then scales from that value to the value plus the value defined by the FinalScale property.
  • Await – a boolean that represents whether the animation should be awaited, or whether it should be allowed to complete in the background. If this value is omitted the default value of false will be used.

The following code example demonstrates using the EventHandlerBehavior and ScaleAction classes to implement a scaling animation that expands and contracts an Image control when a Button is clicked:

<Image x:Name="image" Source="monkey.png" Opacity="0" VerticalOptions="CenterAndExpand" />
<Button Text="Run Animation">
<behaviors:EventHandlerBehavior EventName="Clicked">
<behaviors:ScaleAction TargetObject="{x:Reference image}"
<behaviors:ScaleAction TargetObject="{x:Reference image}"
="SpringOut" />

When the Button.Clicked event fires, two ScaleAction instances execute over 6 seconds. The first ScaleAction instance expands the Image instance to twice its size over 3 seconds (3000 milliseconds), and uses the SpringIn easing function to cause the animation to accelerate towards the end. Once the first ScaleAction instance has executed the second ScaleAction instance begins. This is because the first ScaleAction instance sets the Await property to true. The second ScaleAction instances causes the Image to contract back to its original size over 3 seconds (3000 milliseconds), and uses the SpringOut easing function to cause the animation to decelerate towards the end.

The advantage of using the ScaleAction is that it’s possible to invoke animations through XAML, rather than having to use C#. In addition, when combined with behaviors, a scaling animation can easily be invoked from XAML when a behavior occurs, such as event firing, or when a piece of data changes.

The sample application that this code comes from can be downloaded from GitHub.


The ScaleAction class allows scaling animations to be invoked through XAML when a behavior occurs, such as an event firing, or when a piece of data changes.

June 29, 2016 9:04 GMT

Me gusta, no me gusta, me gusta…


Hace poco más de un mes tuve la oportunidad de asistir a un evento de desarrollo de software donde me llamó mucho la atención una charla que mencionaba en su título “soft skills”. ¿Se podría traducir como habilidades sociales? El resto de ponencias trataban sobre tecnología pero en ésta era lo último que importaba: importaban las personas.

Me resulta curioso, y a veces desconcertante, que con el paso de los años la informática, mi pasión desde que soy chico, tiene más sentido para mí si lo que haga en relación involucra a las personas. Hoy en día, en mi trabajo, disfruto mucho yendo a la mesa de un compañero y preguntándole ¿te puedo ayudar en algo? Si tiene un problema, algo que le atasca, si puedo lo cojo para que él avance, e intento resolverlo. No me genera tanta ilusión el coger un problema técnico y enfangarme hasta los codos (que un poco también), como hacer que ésa persona tenga un momento de tranquilidad, pueda enfocarse en otro tema y, si he tenido “suerte”, volver al día siguiente con una solución a nuestro problema. Porque los problema en los equipos son tuyos y míos, de los dos. Esto lo aprendí de mi primer trabajo en Microsoft y me ha acompañado ya más de diez años…

Volviendo al tema, soft skills, “capacidades suaves” (qué romántico ¿no?), habilidades sociales. De todo lo que John Sonmez, la persona que lo impartía, habló, me dejó clavado en el asiento la siguiente afirmación:

Todo lo que te gusta en la vida dejará de gustarte

Quizá para ti que leas esto es de cajón, lo has pensado 1.000.000 de veces, o no te mueve nada por dentro. Para mí fue entre revelador y doloroso. ¿Cómo que todo lo que me gusta en mi vida dejará de gustarme? ¿Que la informática dejará de gustarme? ¿Que dejará de gustarme leer sobre Steve Jobs? ¿Incluso una pareja? Vamos no me jodas, pensé.

Lo siguiente que se me vino a la cabeza fue: ¿si todo lo que me gusta me puede dejar de gustar, por qué entonces me esforcé tanto en ser un buen novio, en hacer mi trabajo de puta madre, por qué he decidido levantarme todos los días a las 6 de la mañana para dedicar 1 hora a mis proyectos personales? Si todo me puede dejar de gustar, quizá no merezca tanto la pena el esfuerzo…

Digamos que aún, un mes y pico después, no tengo una estrategia clara para mí mismo respecto a esto. En 2015 conocí a un amigo de un amigo, una persona que me saca como unos veinte años que, en un momento hablando en privado, me regaló una joyita:

Marcos, ¿tú sabes qué he aprendido en la vida con mi edad? Que el truco está en el movimiento

Yo a veces tengo tantas cosas que me gustaría hacer que, todavía a veces me ocurre, acabo por no hacer ninguna de ellas, sólo porque no me decido, no las sé priorizar. Sin darme cuenta las ordeno por la vinculación emocional que me generan y, a veces, es mejor dejar las emociones a un lado. Últimamente estoy poniendo en práctica una técnica súper sencilla: cuando no sé que hacer, hago cualquier cosa. (La madre que me trajo porque la conozco hace años, pero la he usado más bien poco…) Paso de la ansiedad de no saber escoger, al disfrute de hacer algo. Sea cocinar, escribir esto que lees, u ordenar una estantería.

Cuando no sabes que todo te puede dejar de gustar, y algo te deja de gustar, le puedes coger hasta asco. A mí me ha pasado en algún momento con la informática. De tanto que me gustaba, de tanto tiempo que le dedicada, le cogí asco. Simplemente me vino bien entrelazarla con otras cosas, otros hobbies por ejemplo. Y me volvió a gustar.:-)

Por último, cuando estás en un momento en el que algo no te gusta, te estás dando cuenta además, y se genera una situación incómoda, lo mejor que me ha funcionado hasta el día de hoy es tirar de disciplina. Si tengo que seguir haciéndolo, el componente de disfrute, que está bajo mínimos, lo voy cambiando por el “hacerlo porque sí”, con la consciencia de que esto que me está pasando es normal, nos ocurre a todas las personas, y sigo con ello porque en el fondo sé que es algo bueno en mi vida. John Sonmez, además, es el consejo que dio en su charla: ser disciplinado.

Si eres capaz de aquello que te gusta vivirlo gota a gota quizá no te ocurra jamás todo esto. O quizá sí pero en cosas muy puntuales. Sea como sea, recuerda que todo aquello que te gusta hoy, te dejará de gustar en algún momento. Depende de ti, de mí, qué hagamos entonces. Si sigue teniendo sentido, sigue haciéndolo, y busca el disfrute en otra cosa. Lo que sea: vete a lavar el coche, que seguro tiene más polvo que la tele por detrás.

PD: Siempre que escribo estas cosas me imagino que habrá alguien que lo lea y se sentirá identificada/o. Si es tu caso, ¿eras consciente de esto, cómo lo gestionas? ¡Muchas gracias de antemano!