Notes from my March 6 - 11 2017 trip to Barcelona with Ksenia.

General Notes

We didn’t use the transit system. Either stuff was within walking distance or we took cabs. Barcelona has it’s own cab app (works like Uber), so you can hail one that way if you wish. The app is called Helo. I found the app through Google maps. Input the address in Google Maps you want to get to, and then click on “Hail a Cab” and app suggestions will pop up.

We like using our credit cards when we travel abroad (we have one that has no foreign transactions fees), and Barcelona was very credit-card friendly (unlike Germany….ugh that’s a whole other story). Also, I find that more and more places ask (when charging stuff to your CC) if you want to pay in Euros or US dollars. Definitely pay with Euros. The price difference may be small, but it starts to add up if you keep using your CC.

Eat

Ham. There are several types but what you want to eat will be the black hoof iberico. Sweat, salty, tender, melt in your mouth. Amazing.

There’s more foie here than I would have expected. We wound up eating foie and ham each and every day. It was delightful.

Tapas tend to be very regional dishes in Spain. Which means that you can only find a handful of different options wherever you go. Except Barcelona. Barcelona never had the tapas tradition, so when they started becoming a thing Barcelona just made everyone else’s and then invented some new ones. This means that if you want to try all the tapas, Barcelona is where you want to be. I enjoyed eating tapas at the bar. It’s nice to have the bartender around so you can easily and quickly order another dish. And you will be ordering another dish.

Pan con tomate or tomato bread is a common dish where they rub a mushy tomato on some crispy (sometimes purposefully stale) bread and drizzle some olive oil over it. It is delicious and you can find it everywhere. If a spot doesn’t have good tomato bread then it’s probably not worth eating anything else there.

Reservations aren’t required but can be helpful.

  • Tapas @ Catalana
    • Good not great.
  • La Pepta
    • We went to eat here twice! Ksenia still talks about the foie gras topped with white chocolate and hazelnut shavings. They do giant gintonics.
    • In can get VERY crowded in there so if you get there RIGHT at 7:30pm (when they re-open for dinner), you should be able to get a seat at the bar.
  • Walking Food Tour of Gracia
    • Gracia is a neighborhood with a unique identity and great food. This tour was one of our highlights of the trip! Highly recommend! It just so happened that on our tour it was me, Ksenia, and one other person, plus the guide. Gracia is delightful! Also, if you like getting one-of-a-kind clothing, this is the place to walk around! K got several shirts for herself and mom here. In one shop, the owner/designer had her studio right behind her, with all the materials she needed to make the shirts.
    • Stops:
      • Con Tosca - a cute cafe where we had sausage on tomato bread and a glass of cava.
      • Local market
        • I Conservas Gloria for olives
        • Fabregas for ham
        • La Trobada del Gourmet for cheese and jams
      • Oil Sal a salt and oil store where we had olive oil tasting
      • l’Anxoveta a cute bar, we had tomato bread and crouqets
      • Pastisseria Principe a Syrian pastry shop that’s been there for 30 years
      • Bodega Ca’l Pep an ancient very local bar. We had vermouth, pickled anchioves, and sausage.
      • La botigueta del Bon Menjar a small shop that sells premade food. very local
      • Pastissera Ideal another pastry shop. We had cremat - a Spanish version of creme brulee (it actually predates the French version)
  • La Pubilla
    • My favorite restaurant. I’d recommend a reservation, or just getting there when they open.
    • We ate here twice. When we came back the second time we were welcomed like old friends.
    • Between K and I, we ate like 90% of the menu between the two trips there. And we were not disappointed.
    • The waiter was gave us some great wine recommendations, they have some really local stuff there. Like 1km away local.
    • Best croquets we had
    • Homemade pate
    • The capacio was one of the best things I ate on this trip.
  • Alta Taberna Paco Meralgo
  • Tapeo del Born
    • Near the Picasso Museum. We ate here on our last night, at the bar.
    • It feels a bit more touristy but the food was still good. K liked it more than I did.
    • When we ordered our food, one of the guys behind the bar asked if we had come there before because he was impressed with our choices.
    • The Foie Gras burger was good.
  • Mercado de la Boqueria
    • Not a restaurant, but it has plenty of stalls in it where you can get all sorts of food
    • Butchers sell “meat cones” - charcuterie in a paper cone.
    • Fresh juices
    • Hot food
    • Candies
    • etc.

Drink

Gintonic has recently become a thing in Spain. According to a bartender I spoke with Hendrix put a lot of ad dollars into the area and it worked. There are dedicated gin bars with dozens if not hundereds of bottles to choose from. Josh loved these places. A lot.

While gin is the new fad, vermouth is the traditional drink. The early afternoon is called “the vermouth hour”. It’s when you’re supposed to get together with some friends and have a glass of vermouth, a few sardines, and chat.

Another classic is cava, a Spanish sparkling white wine.

  • Elephanta
    • A gintonic bar that also has a great tea list.
    • Several dozen options for gin, with useful descriptions.
    • The menus are on the back of LPs.
    • They do flights
  • Bobby’s Gin
    • Hundreds of bottles of gin
    • Very knowledgeable bartenders
    • Lots of obscure and local gins
    • No food

Do

Barcelona is the city of Gaudi.

  • Gaudi
    • Sagrada Familia
      • Definitely worth booking a ticket with a tour, the “guided experience”, as the tour guide will point out elements to you that you will have missed on your own. Tickets
      • Definitely purchase online! You can choose which time you want to go in.
      • Entrance will be on the “old” side, not the Cubist side.
      • We went in the afternoon and the lighting through the orange/red stained glass windows was AMAZING inside because the sun was setting.
      • This was by far my favorite part of Barcelona that I couldn’t eat or drink.
    • Casa Batlló
      • This house is AMAZING! Don’t miss it!
      • The audioguide is worth it. There are so many details.
      • The interior was really cool with all sorts of curved walls and doors. It felt like being in an underwater fairytale.
    • Park Guell (aka Gaudi Park)
      • So the park is free BUT if you want to go visit the section of the park with all the Gaudi stuff you have to buy a ticket and it’s timed entrances. We didn’t realize this when we went (this is a very recent thing, as the entire thing used to be free) We got there at like 3, got our ticket for 4:30, and in between that time we walked around through the rest of the park which has several layers. It is a nice walk and you have some great views. The Gaudi section will be crowded. So if you’d like, plan in advance and get tickets online for a timed entry. FYI: the entire park is up on a hill! We went to the Park after we did the food tour, because it was essentially a straight shot from the endpoint of the tour (and because stuff was closed at 2pm-ish).
    • Palau Guell
      • My least favorite of the Gaudi sites, perhaps because it was the last.
      • The roof has amazing views but is very sloped. It may not bother some people but I was terrorfied up there. Frozen and refused to move without holding on to something.
  • Free Walking Tour
    • We did three of these in Germany and one in Barcelona. Really great way for you to quickly learn the lay of the land, the history, and some great anecdotes.
  • Picasso Museum
    • I’m a huge fan and this museum is in a very nice building too! Also some good shopping in the area too!
  • La Rambla
    • Very touristy so keep an eye out for pick pockets.
    • Crowded
    • Only worth it as a way to get to Mercado de la Boqueria
  • Papirum
    • Paper store that sells hand, bound deckled, leather notebooks.
  • Museu d’Art Contemporani de Barcelona
    • Very modern very out there. We did not enjoy this museum. It’s the type of modern art that people sneer at when they think of modern art. Like a banquet table that is set with plates of rice died to look like the flags of various nations, but then they left all the food to rot. Or a wall made out of loaves of white bread.

Sleep

Hotel Praktik Bakery is a hotel with a bakery on the first floor. Sounds a bit gimmicky except that they legitimately have the best bread in the city. There are lines out the door of locals and tourists. You can see the bakers making the bread in the front window. The pastries are amazing, and the grab and go sandwich I got for breakfast was legitimately one of the best sandwiches I ever had.

They do a continental style breakfast, but it’s better to just get something from the bakery directly.

If a bakery doesn’t tickle your fancy, Praktik has other themed hotels in Barcelona, including a wine bar slash hotel.

Oh, and the rooms have rain showers.

All of that, plus a great location.

Chrome, Tips, GitHub, PR comments edit

Sometimes when I’m working on a long pull request in GitHub and switch back to the PR tab after a while of looking at other pages the Pull Request page will automcaticall reload itself. Most of the time this is fine, but sometimes I wind up losing a lot of state (scroll position, which files were loaded manually, which files had been collapsed, etc). It turns out that Chrome will garbage collect tabs that are taking up a lot of memory that you may not be using. Chrome allows you to disable this behavior by going to chrome://flags/#automatic-tab-discarding. Simply set the drop down to ‘Disabled’.

I typically don’t want to keep this setting once I’m done with my PR, so I’ll then jump into slack and ask it to /remind me to fix chrome://flags/#automatic-tab-discarding in the morning

GitHub Pages, SSL comments edit

Adding a certificate to your GitHub Pages site so that all of your traffic can use HTTPS is easy… if you don’t use a custom domain name. If you do have a custom domain, then you need to do a little work and a (free) Cloud Flare account to get it going.

  1. Create your free acount on https://www.cloudflare.com
  2. Enter your site’s address in the setup bar
  3. Head over to your DNS provider and add the Clod Flare servers as your custom domain servers. e.g. On NameCheap
  4. Optionally, you can head back to Cloud Flare and set up a page rule to redirect all HTTP pages to redirect to HTTPS. Just add a rule to match http://*quintussential.com/*
  5. Wait. DNS has to happen now.

Thanks to Hacker Noon for pointing this out.

Mermaid, Tools comments edit

Mermaid is a tool that will generate diagrams from a basic definition language.

The mermaid website has full description of the language and features: https://knsv.github.io/mermaid/#syntax

A Simple Example

The following snippet will create a simple sequence diagram.

sequenceDiagram
    Alice->>John: Hello John, how are you?
    John-->>Alice: Great!

The above diagram renders as:

sequenceDiagram Alice->>John: Hello John, how are you? John-->>Alice: Great!

Tools

There are various tools that you can use to edit and save diagrams as images

Mermaid CLI

Pros and Cons

Pros

  • Export diagram as an image

Cons

  • No live updating diagram as you type
  • Syntax requires a non-standard but simple header of ```mermaid

Setup and Use

  1. Install node.js
  2. Install the mermaid npm package
     npm install -g mermaid
    
  3. Install the phantomjs npm package
     npm install -g phantomjs
    
  4. Save the following diagram definition to a file sequence.mmd
     sequenceDiagram
         Alice->>John: Hello John, how are you?
         John-->>Alice: Great!
    
  5. Run mermaid command
     mermaid sequence.mmd
    
  6. Open the image found at sequence.mmd.png

sequence.mmd.png

Visual Studio Code

Pros and Cons

Pros

  • Live updating diagram as you type

Cons

  • No easy way to export diagram as an image
  • Syntax requires a non-standard but simple header of ```mermaid
  • Supports the activate/deactivate keywords that are unsupported by other processors

Setup and Use

  1. Download and install Visual Studio Code (this is entirely different than the “normal” Visual Studio you use to write C# code)
  2. In Visual Studio Code download and install the Mermaid Preview extension
  3. Restart Visual Studio Code when prompted
  4. Create a new markdown file named sequence.md
  5. Paste in the following diagram definition (including the lines that start with three backticks)
         ```mermaid
         sequenceDiagram
             Alice->>John: Hello John, how are you?
             John-->>Alice: Great!
         ```
    
  6. Press <control-p> to bring up the Visual Studio Code command window
  7. Type in > Preview Mermaid Diagram
    • Include the > character
    • You only need to type enough of the command that it shows up in the menu
    • You can type in various short cuts that will also bring up the command quickly
      • > Mermaid
      • > PMD (just the initials)
  8. Click on any of the text in the left pane that is part of the diagram definition

Sample Diagram in Visual Studio

Atom

Pros and Cons

Pros

  • Live updating diagram as you type
  • Export diagram to PNG or SVG

Cons

  • Exported diagram has a blank background (you need to manually open the file and add a non-transparent background to be able to view the image)

Setup and Use

  1. Install Atom editor
  2. Install Mermaid Preview extension
  3. Create a new markdown file named sequence.mmd
  4. Paste in the following diagram definition
     sequenceDiagram
         Alice->>John: Hello John, how are you?
         John-->>Alice: Great!
    
  5. Press the Packages -> Mermaid Preview -> Toggle Preview button
  6. To export as image right click the diagram and select Save as PNG

Sample Diagram in Atom

Docker, Jekyll comments edit

GitHub Pages have some great features that I’m excited about. Markdown makes writing code-centric blog posts easy. Storing posts in git is great – history, diffs, and no need to learn a new tool. Not to mention simple hosting by GitHub.

There’s just one minor issue, setting up a decent environment on a Windows machine can be troublesome if you’re not alread a Ruby developer. I’ve tried twice now and run into issues both times. Multiple versions of Ruby, non-Windows friendly libraries, failed SSL certs, and probably a few more things that I’ve forgotten. Next I thought I’d try it on Linux on Windows. For the most part that worked well, except some auto-reload features didn’t work well.

It’s almost as if I would be better off trying to run the environment on a Linux machine. Seeing as I don’t have a spare machine and hate running VMs on my work laptop, I’m probably not running Linux any time soon.

All I really want is a preconfigured environment that I can download quickly and not have to do anything to setup. Is that too much to ask? Apparently not. Heading over to Docker Hub, I found several Docker Images for exactly the environment I wanted. I blindly went with the one with the most downloads. There was one minor hicup. The instuctions use the Linux variable $PWD to mount the volume from the host machine to the Docker image. That just needed to be translated to %CD%. With that down, I was able to point the browser on my Windows machine to localhost:4040/ and my website was up. I could edit any file with whatever Windows tool I was comfortable with (ironically, Vim), save it and my site would be regenerated.

All told, I was up and running in about 15 minutes, including download time and writing two simple batch files to start and stop the containers.

StartDocker.bat

@ECHO off
ECHO Starting gpages container

docker run -t --rm           ^
    --name gpages            ^
    -v "%CD%":/usr/src/app   ^
    -p 4000:4000             ^
    starefossen/github-pages

StopDocker.bat

@ECHO off
ECHO Stopping gpages container
docker stop gpages

vim comments edit

I’ve been using Vim for close to 15 years now and it always amazes me. I needed a quick and easy way to encrypt some files on a thumb drive when going from one computer to another. After about 5 seconds of googling I see that as always, vim’s got my back.

First off, you can optionally select your encryption scheme by doing :setlocal cm=blowfish2. There are other options, but that’s the strongest encryption available. Next all you need to do is set the password by typing: :X (note that it is a capital X). You’ll be prompted for the password. After that just close vim as normal. You can cat out your file on the terminal to double check that it’s encrypted.

When you repopen the file in vim, you’ll be prompted to enter the password to decrypt the data.

If you want to save the decrypted file, just clear out the key by doing :set key= and then save the file.

Background

Okay, so I don’t really know why I’d use this, but I just came across Ninject.Extensions.Interception. Basically it allows you to intercept an arbitrary method call and run code before and after the call. Even replace the method entirely.

You could use this to achieve many things you would use Aspect Oriented Programming to do. Post Sharp has a great breakdown on what those use cases are and why it’s a valid approach to solving certain problems.

The canonical use case for this is the ability to easily add logging when you enter and exit a method.

For example, the following code would log all calls to the SomeSuperImportantMehod

[LogAllMethods]
public class CanonicalLogging
{
  public virtual int SomeSuperImportantMehod(string input, int maxItems)
  {
    return CalcualteReallyImportantThing(input, maxItems);
  }
}

And here’s an example of what the output could be

2017-05-05 13:45:54.64723 CanonicalLogging.SomeSuperImportantMehod called with parameters:  {input:  "Hello World", maxItems: 34 }
2017-05-05 13:56:56.94949 CanonicalLogging.SomeSuperImportantMehod returned "42" after running for 11:02:30226

Walkthrough

For the example I’m going to build an implementation of the Dispose Pattern with a base class that will handle all of the actual disposing logic. I’ll use a custom interceptor to ensure that once my objec thas been disposed all future calls to it will throw an ObjectDisposedException.

To get started you first need to be using Ninject. I’m going to assume you have a bit of a background with Ninject. Just in case you don’t, the quick version is that it’s a .Net IoC container. Basically that means that after doing a little configuration you can ask it for an instance of any type you want and it will give it to you, creating it and its dependencies if it needs to.

Another thing to be aware of is that there are two options, either use LinFu or CastleCore for the proxy generation. As far as I can tell, this decision doesn’t really impact much. Just pick whichever framework you like, or one at random. I already use CastleCore in other projects (the Ninject factory extension depends on it), so I’m going with that one.

Install-Package Ninject.Extensions.Interception.DynamicProxy

ADisposable

Next I’ll create the base ADisposable that all of my custom disposable objects will inherit from.

    [Disposable]
    public abstract class ADisposable : IDisposable
    {
        public ADisposable()
        {
            IsDisposed = false;
        }

        ~ADisposable()
        {
            Dispose(false);
        }

        internal bool IsDisposed { get; private set; }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void OnDispose();

        private void Dispose(bool disposing)
        {
            if (IsDisposed) return;

            if (disposing)
            {
                OnDispose();
            }

            IsDisposed = true;
        }
    }

There two things worth pointing out here. First, the internal IsDisposed property. This will be used by our interceptor later to determine if the object has been disposed. The other thing worth noting is the Disposable attribute. That’s a custom attribute I defined. It inherits from Ninject.Extensions.Interception.Attributes.InterceptAttribute. This is the first step into using interceptors, so let’s take a look.

DisposableAttribute

using Ninject;
using Ninject.Extensions.Interception;
using Ninject.Extensions.Interception.Attributes;
using Ninject.Extensions.Interception.Request;
using System;

namespace Interceptors
{
    [AttributeUsage(AttributeTargets.Class)]
    public class DisposableAttribute : InterceptAttribute
    {
        public override IInterceptor CreateInterceptor(IProxyRequest request)
        {
            return request.Kernel.Get<DisposableInterceptor>();
        }
    }
}

There’s only one method that we have to worry about CreateInterceptor. This just lets the system know what interceptor to use when creating the implementation of ADisposable. You can see here that I added the AttributeUsage to specifically target only classes. Be default InterceptAttributes can be put on anything, although they really only make sense on method (including properties) and class definitions. When the attribute is placed on the class, it impacts all of the methods. In fact there is a neat DoNotIntercept attribute that you can use to exclude certain methods from the class wide interceptor.

In my example, I used the request to get an instance of the Kernel so I could resolve the interceptor I wanted. That was mostly just to illustrate that you can get a hold of the kernel. In this instance, I could have just as easily newed up the DisposableInterceptor. Speaking of which, DisposableInterceptor is where the most interesting code is. We’ll look at that next.

DisposableInterceptor

using Ninject.Extensions.Interception;
using System;

namespace Interceptors
{
    public class DisposableInterceptor : SimpleInterceptor
    {
        protected override void BeforeInvoke(IInvocation invocation)
        {
            base.BeforeInvoke(invocation);

            var disposable = invocation.Request.Target as ADisposable;

            if (disposable != null && invocation.Request.Method.IsPublic)
            {
                if (disposable.IsDisposed)
                {
                    string methodName = invocation.Request.Method.Name;
                    throw new ObjectDisposedException(disposable.GetType().Name, $"{methodName} called after object was disposed");
                }
            }
        }
    }
}

It inherits from SimpleInterceptor and overrides BeforeInvoke. As you may guess, there’s an AfterInvoke as well. If you wanted to, you could set the return value of the method by setting invocation.ReturnValue in BeforeInvoke. Or in AfterInvoke you could check to see if it’s within certain limits.

Anyway, in this example all I care about is overriding BeforeInvoke to check if

  1. The instance being invoked is an instance of ADisposable
  2. The method being called is public (no need to worry about private methods being called since they’d have to be called from public ones to begin with)
  3. If the instance had already been disposed.

In order to do all of those things, I just need to inspect sub-properties of the passed in instance of IInvocation. If all of those things are true, then we just throw an exception.

Now that we see the interception code is straight forward, let’s put it all together so that we can use it.

Sample Service

public interface ISomeService : IDisposable
{
    void SomeMethod(string msg);
}

public class MyService : ADisposable, ISomeService
{
    public void SomeMethod(string msg)
    {
        Console.WriteLine(msg);
    }

    protected override void OnDispose()
    {
        Console.WriteLine("Disposing MyService");
    }
}

The first thing to look at is the sample service interface and implementation. ISomeService is just a simple interface that inherits from IDisposable and has a single method to implement. MyService inherits from ADisposable and ISomeService and pretty much does the minimum it needs to do to implement them.

Notice though that neither of them are aware of either Ninject or any of the interceptors. They are bog standard C# classes.

Resolving an Interface

private static void TestResolvingInterface()
{
    Console.WriteLine("Testing resolving an Interface from the Ninject Kernel");
    using (var kernel = new StandardKernel())
    {
        kernel.Bind<ISomeService>().To<MyService>();

        ISomeService service = kernel.Get<ISomeService>();

        TestService(service);
    }
}

private static void TestService(ISomeService service)
{
    Console.WriteLine("    " + service.GetType().Name); // Prints out "ISomeServiceProxy"
    service.SomeMethod("    Hello World");
    service.Dispose();

    try
    {
        service.SomeMethod("    This call should fail");
    }
    catch (ObjectDisposedException odex)
    {
        Console.WriteLine(odex.Message);
    }
}

In the first method, TestResolvingInterface, we do some very standard Ninject setup. Create a standard kernel, add some bindings, and then resolve our interface. Again, none of this is even aware of the interceptors. Ninject picked up on it from the attribute and that was enough.

The output for this is:

Testing resolving an Interface from the Ninject Kernel
    ISomeServiceProxy
    Hello World
Disposing MyService
SomeMethod called after object was disposed
Object name: 'MyService'.

You’ll notice that service is an instance of ISomeServiceProxy, not MyService. Ninject wrapped our instance of MyService, adding the extra functionality to the proxy without actually impacting our class.

You’ll also see that the second call to SomeMethod does indeed fail with an ObjectDisposedException.

Resolving a Concrete Class

Now that worked all well and good. But what if we resolved just a class instead of an interface? Well that’s where this starts to break down as we’ll see in the code below.

private static void TestResolvingConcreteClass()
{
    Console.WriteLine("Testing resolving a Concrete Class from the Ninject Kernel");
    using (var kernel = new StandardKernel())

    {
        MyService service = kernel.Get<MyService>();
        TestService(service);
    }
}

private static void TestService(ISomeService service)
{
    Console.WriteLine("    " + service.GetType().Name); // Prints out "MyServiceProxy"
    service.SomeMethod("    Hello World");
    service.Dispose();

    try
    {
        service.SomeMethod("    This call should fail");
    }
    catch (ObjectDisposedException odex)
    {
        Console.WriteLine(odex.Message);
    }
}

So now we’re resolving a MyService directly and passing it to the same test function as the previous example. Let’s look at the output.

Testing resolving a Concrete Class from the Ninject Kernel
    MyServiceProxy
    Hello World
Disposing MyService
    This call should fail

We’re getting a proxy wrapping our class again (MyServiceProxy), which is a good sign, but then we see that the second call to SomeMethod actually succeeds. Why is this?

This is probably the biggest caveat in the entire thing. The interceptors can only impact virtual methods. Interface methods are by nature virtual so they are no problem. But when it comes to concrete classes, unless the method is explicislty marked as abstract or virtual it can’t touch them. As I mentioned above, Ninject is dynamically creating an implementation of the requested object with custom implementations of all the methods. If MyService had been sealed, Ninject would have thrown a TypeLoadException when it was resolved because it couldn’t subclass the type.

Summary

As mentioned above, the major caveat is that it only works with virtual methods. If you always use interfaces, then you will be just fine, but if you don’t the interceptors will silently fail to be called.

Other than that, this is a pretty easy to use tool that can provide a lot of power. Another obvious use case for this is automating INotifyPropertyChanged. It’s so obvious that it comes premade. Just check out the NotifyOfChanges attribute.

Jekyll, update comments edit

This is my first post on my new blogging engine. I’m using GitHub Pages now. So far I really like it. It’s nice and easy. I have been a big fan of markdown for some time now. Rich text that I can easily create in vim? Yes please! Creating templates for pages and content that I can easily create by adding structured data files to a folder? Yes please!

comments edit

Following up on CoolWhip, ChocolateyCoolWhip is a nuget package that makes creating, packaging, and deploying your code through Chocolatey.org simple. Like CoolWhip, all you need to do to publish a new release is create release in GitHub.

Chocolatey?

In case you aren’t familiar, Chocolatey is a package manager for Windows built on top of NuGet and PowerShell. It allows users to download and install thousands of software programs with a single command. For example, to install nodejs, all you would need to do is open up a command prompt and enter

> choco install nodejs.install

Getting Started with ChocolateyCoolWhip

To get started, install the nuget package into your project. The first thing you’ll notice is that it creates nuspec and AppVeyor configuration files. Chocolatey uses the nuspec as metadata for your package, the same way NuGet does.

Once setup, all you need to do to update your package on Chocolatey.org is create a release in GitHub. ChocolateyCoolWhip will pull the version information directly from the release name and kick off a build in AppVeryor. You have complete control over versioning your application

Configuration is simple:

  1. Connect AppVeyor to your GitHub repo
  2. Install the NuGet package >Install-Package ChocolateyCoolWhip
  3. Update the generated nuspec file with your project’s information
  4. Add your authorization tokens to the AppVeyor.yml file
  5. Save/commit your changes

Once this is set up, all you’ll need to do in order to release (or update) your package on NuGet is create a GitHub release with the version number.

There is full step by step documentation in the wiki.

Happy Coding.

this post was originally on the MasterDevs Blog

comments edit

CoolWhip is a NuGet package aimed at making and deploying other NuGet packages easier. With CoolWhip, creating a Release in GitHub automatically pushes that release to NuGet.

Once you’ve installed CoolWhip into your project it will create a nuspec file and AppVeyor configuration file. These will work together to package your project and automatically upload it to NuGet.org.

Once setup, all you need to do to update your package on NuGet.org is create a release in GitHub. CoolWhip will pull the version information directly from the release name and kick off a build in AppVeryor. You have complete control over versioning your application.

To configure CoolWhip you need to

  1. Connect AppVeyor to your GitHub repo
  2. Install the NuGet package >Install-Package CoolWhip
  3. Update the generated nuspec file with your project’s information
  4. Add your authorization tokens to the AppVeyor.yml file
  5. Save/commit your changes

Once this is set up, all you’ll need to do in order to release (or update) your package on NuGet is create a GitHub release with the version number.

There is full step by step documentation in the wiki.

Happy Coding.

this post was originally on the MasterDevs Blog

comments edit

I’m OCD when it comes to my code. I don’t like to have any warnings. I wanted to configure my TeamCity builds to fail if there were any warnings in the projects. My first option is to tick the “Treat warnings as errors” box in the project settings. This had a few problems

Problem 1.

I’d have to remember to do it for every project in my repo, including all the projects I make in the future. Even worse, everyone on my team would have to remember to do that too. That’s not something I could rely on.

Problem 2.

While warnings are just errors that you’re ignoring, I will admit that it is convenient to be able to ignore some things some times. I’m fine with debugging and running locally with some errors. I really only wanted to stop people from committing code back to master with warnings. I couldn’t care less about bad hygiene the have when working locally.

The Solution

In searching, I found David Gardiner’s blog post in which he creates a power shell script to edit the xml in each csproj file. It looks simple enough so I removed the TFS bit and added it as a build step in my TeamCity flow. It runs right before compiling my code.

Get-ChildItem -Recurse -Filter "*.*csproj" | % {
    Write-Host $_.Name
     
    $filename = $_.Fullname
     
    $proj =
1
( Get-Content $_.Fullname ) $xmlNameSpace = new-object System.Xml.XmlNamespaceManager($proj.NameTable) $xmlNameSpace.AddNamespace("p", "http://schemas.microsoft.com/developer/msbuild/2003") $nodes = $proj.SelectNodes("/p:Project/p:PropertyGroup[@Condition and not (p:TreatWarningsAsErrors)]", $xmlNameSpace) $touched = $false $nodes | ForEach-Object -Process { $e = $proj.CreateElement("TreatWarningsAsErrors", "http://schemas.microsoft.com/developer/msbuild/2003") $e.set_InnerText("true") $_.AppendChild($e) | Out-Null $touched = $true } if ($touched) { Write-Host "Checkout $filename" $proj.Save("$($filename)") | Out-Null } }

this post was originally on the MasterDevs Blog

.NET, C# comments edit

Sometimes it is just much easier to deploy a single assembly that includes all dependencies. ILRepack and ILRepack.MSBuild.Task will do just that for you. Since I like to have Visual Studio and my build environment do this for me, I went with ILRepack.MSBuild.Task.

The Sample

In order to showcase packing an assembly into my program, first I need a program that has a dependency. I decided to go with a simple console app that has a dependency on the Humanizer NuGet package to tell you how long you have to wait until your birthday.

>Repack.exe
Usage:   repack [date]
  Prints how long it is until your birthday.
  If you don't supply your birthday, it uses mine.
 
23 weeks until your birthday

I created a new console project in Visual Studio and named it Repack. I then included the Humanizer DLL using the NuGet package manager.

You can find the source code on github.

Using ILRepack

All you need to do is add the following snippet at the end of your .csproj file. To do this, you can open up the .csproj file in notepad or your favorite text [editor])(http://www.vim.org).

<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
 
 <ItemGroup>
  <InputAssemblies Include="$(OutputPath)\$(AssemblyName).exe" />
  <InputAssemblies Include="$(OutputPath)\*.dll" />
 </ItemGroup>
 
 <ILRepack
  Parallel="true"
  Internalize="true"
  InputAssemblies="@(InputAssemblies)"
  TargetKind="EXE"
  OutputFile="$(OutputPath)\$(AssemblyName).exe"
 />
</Target>

Because we name the target AfterBuild, this code will automatically be run after msbuild or Visual Studio builds our project. Setting the condition ensures that this will only run when we are in release mode. You can definitely run this on debug builds, but it’s less likely that you’d want to.

The ItemGroup specifies lets us create a list of assemblies to include in the package. The first assembly should be your assembly. In my example it will be my executable file Repack.exe. Next, I include all the DLLs in the output directory. This way, if I add a new dependency later, it will be included automatically.

Note that the order does matter. You will want to put the .exe first in this list.

Next all we need to do is call ILRepack. You can specify the output file to be anywhere you like, but in this example I overwrite the existing Repack.exe with the packed version.

Once you rebuild your project (in release mode), you can copy the EXE anywhere you want and it will run.

Summary

ILRepack.MSBuild.Task let’s you package DLL’s into your EXE file so you can copy just the executable anywhere and not have to worry about deploying the dependencies as well.

Full sample code can be found on github.

Happy coding.

this post was originally on the MasterDevs Blog

C#, Tools comments edit

Occasionally I need to FTP into one of my Azure websites. Sometimes it’s to look at the logs; other times to upload a few files. Just about every time I go to do this, I realize that I don’t know the credentials. So I go and download the publish profile and open it up in my favorite text editor to get the FTP information and manually enter that in FileZilla.

I quickly became tired of doing this, so I wrote a console app that will do it for me. The source code and executable are available on my GitHub.

Usage

  1. Download your publish profile
  2. Run the command line tool
  3. Import the config file to FileZilla

Download your publish profile

Log on to the Azure management portal for the website you want to FTP into. On the right side of the dashboard page you will see an option to “Download the publish profile.” Click it and you’re on your way.

When downloaded the file will look something like this:

<?xml version="1.0" encoding="utf-8" ?>
<publishData>
  <publishProfile
    profileName="TestSite - Web Deploy"
    publishMethod="MSDeploy"
    publishUrl="testSite.scm.azurewebsites.net:443"
    msdeploySite="testSite"
    userName="$testSite"
    userPWD="test password"
    destinationAppUrl="http://testSite.azurewebsites.net"
    SQLServerDBConnectionString=""
    hostingProviderForumLink=""
    controlPanelLink="http://windows.azure.com"
    webSystem="WebSites">
  </publishProfile>
  <publishProfile
    profileName="TestSite - FTP"
    publishMethod="FTP"
    publishUrl="ftp://waws.ftp.azurewebsites.windows.net/site/wwwroot"
    ftpPassiveMode="True"
    userName="testSite\$testSite"
    userPWD="test password"
    destinationAppUrl="http://testSite.azurewebsites.net"
    SQLServerDBConnectionString=""
    hostingProviderForumLink=""
    controlPanelLink="http://windows.azure.com"
    webSystem="WebSites">
  </publishProfile>
</publishData>

Obviously, all the pertinent connection information has been scrubbed clean. But you get the idea.

Run the command line tool

Next thing you need to do is run pubToFz.exe to convert the publish profile into a format that FileZilla understands. Assuming the default download location, the command would look like this:

pubToFz %home%\downloads\testSite.publishProfile

By default, the tool creates an file named FileZilla.xml in the current directory. The file will look something like this.

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<FileZilla3>
  <Servers>
    <Server>
      <Host>waws.ftp.azurewebsites.windows.net</Host>
      <Port>21</Port>
      <Protocol>0</Protocol>
      <Type>0</Type>
      <User>testsite\$testsite</User>
      <Pass encoding="base64">base 64 encoded test password</Pass>
      <Logontype>1</Logontype>
      <TimezoneOffset>0</TimezoneOffset>
      <PasvMode>MODE_DEFAULT</PasvMode>
      <MaximumMultipleConnections>0</MaximumMultipleConnections>
      <EncodingType>Auto</EncodingType>
      <BypassProxy>0</BypassProxy>
      <Name>TestSite</Name>
      <Comments />
      <LocalDir />
      <RemoteDir />
      <SyncBrowsing>0</SyncBrowsing>
    </Server>
  </Servers>
</FileZilla3>

Again, this was scrubbed clean.

Import the config file to FileZilla

Now all you have to do is open up FileZilla and import the config file that you just saved.

this post was originally on the MasterDevs Blog

CLI, Tips comments edit

I recently stumbled across DOSKEY while reading StackOverflow. Reading the documentation I stumbled across something old and something new.

>doskey/?

<edit>
F7    Displays command history
F8    Searches command history

I knew about F7 and use it constantly when I’m on the command line. It pops up a scrollable list of your recent commands.

F8 lets you cycle through commands in your history with a search term.

Suppose you had previously typed a complex command. In the example I have below, I used the command echo Foxtrot Golf. To find and execute it again all you need to do is type the beginning of the command and then press the F8 key. In the example, I type echo on the command prompt and cycle through all the commands that start with that by pressing F8. To narrow it down a bit more, I type in echo F and then press F8 to get all the commands that start with that. Note that it is case sensitive.

this post was originally on the MasterDevs Blog

In Android, your options are kind of small for setting a font purely in XML.

In this post, I’ll create a converter so we can specify the font in an MvvmCross binding.

Getting a font

Before going any further, you need to actually get and include a font in your android app. For this example I will be using Fontin. The main reason I’m using it is because it was easy to find and is free. Download the TTF versions and and include them in your project. Add a new subdirectory to the Assets folder in your android project named “font”. Drop the files into that folder and include them in your project. Make sure that the build action is set to AndroidAsset.

If you get the following error, make sure that the font names are spelled exactly the same as the folder and file names, including capitalization.

java.lang.RuntimeException: native typeface cannot be made

In the example from my screenshots, my font name should be: font/Fontin-Italic.ttf.

And again, capitalization matters.

Binding to Typeface

The first step is to use MvvmCross. Next all you really need to do is bind directly to the Typeface property on the TextView. They Typeface property is an instance of of Typeface (nothing surprising there) which meanst that you’ll need a converter.

<TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      local:MvxBind="Text Hello; Typeface StringToFont(FontName)" />

The converter is pretty straight forward:

public class StringToFontConverter : MvxValueConverter<string, Typeface>
{
    private static Dictionary<string, Typeface> _cache = new Dictionary<string, Typeface>();
 
    protected override Typeface Convert(string fontName, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            if (!fontName.StartsWith(@"font/")) fontName = @"font/" + fontName;
            if (!fontName.EndsWith(".ttf")) fontName += ".ttf";
 
            if (!_cache.ContainsKey(fontName))
            {
                _cache[fontName] = Typeface.CreateFromAsset(Application.Context.Assets, fontName);
            }
 
            return _cache[fontName];
        }
        catch (Exception e)
        {
            Android.Util.Log.Error("AndroidFont", e.ToString());
 
            return Typeface.Default;
        }
    }
}

First thing the converter does is to clean the input, ensuring that the font name starts with the directory and ends with the ttf extension. This makes the binding a bit easier in that we don’t have to remember to get the full font path correct.

It then check its static cache to see if it already has an instance of the the font, if not it creates one by calling Typeface.CreateFromAsset. If creation fails it does some logging and return the default typeface. This is important because in my testing VisualStudio hang pretty hard under some circumstances where errors were ignored.

Fire this up, and you’ll see that the font is in fact set.

One problem with this example is that we are forcing the ViewModel to know the correct name for the font. In some cases that’s ok, in others, we won’t want to handle font in the VM layer. Luckily we can use Tibet binding and just bind to a static string in the xml. Just remember to surround it with single quotes.

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    local:MvxBind="Text Hello; 
                   Typeface StringToFont('Fontin-Bold')" />

Sample

Here’s a sample layout putting everything together.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:textSize="40dp"
        local:MvxBind="Text Hello; Typeface StringToFont('Fontin-Bold')" />
 
<!-- Binding to the View Model -->
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16dp"
        android:text="Bind to Typeface:  " />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="24dp"
        android:textSize="24dp"
        local:MvxBind="Text Hello; Typeface StringToFont(SelectedFont)" />
    <MvxSpinner
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:textSize="24dp"
        local:MvxBind="SelectedItem SelectedFont; ItemsSource FontNames;" />
 
<!-- Binding to a constant -->
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16dp"
        android:text="Constant Typeface:  " />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="24dp"
        android:layout_marginBottom="24dp"
        android:textSize="24dp"
        local:MvxBind="Text Hello; Typeface StringToFont('Fontin-Bold')" />
 
<!-- Error -->
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16dp"
        android:text="Error Handling:  " />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="24dp"
        android:layout_marginBottom="24dp"
        android:textSize="24dp"
        local:MvxBind="Text Hello; Typeface StringToFont('Not a font name')" />
</LinearLayout>

The edit box and first text box are bound to the value in the spinner. The second text box is staticly bound to the bold font. The last text box is bound to a value that is not a valid font and defaults to the default Android font.

Here’s a link to the working project on git.

Happy Coding

this post was originally on the MasterDevs Blog

To recap, I’m writing a shopping cart app for Windows Phone, Android, and iOS. The purpose of the app is primarily to let me use Forms. Each post will build on top of the previous one.

Last time I fiddled with async loading and added an application level menu. This week I’m going to add native views on Windows Phone and Android using PageRenders.

Recap and Code

This is the tenth post in the series, you can find the rest here:

  • Day 0: Getting Started (blog / code)
  • Day 1: Binding and Navigation (blog / code)
  • Day 2: Frames, Event Handlers, and Binding Bugs (blog / code)
  • Day 3: Images in Lists (blog / code)
  • Day 4: Search and Barcode Scanner (blog / code)
  • Day 5: Dependency Injection (blog / code)
  • Day 6: Styling (blog / code)
  • Day 7: Attached Behaviors (blog / code)
  • Day 8: Writing to Disk (blog / code)
  • Day 9: App and Action Bars (blog / code)
  • Day 10: Native Views (blog / code)

For a full index of posts, including future posts, go to the GitHub project page.

About Page

I want to add a quick about page to the app. I’ll be honest here, I couldn’t think of a great example where the views would be drastically different depending on the platform. They will probably look almost exactly the same. Specifically, they will contain two buttons that will take the user to this blog, (specifically this post), or to the GitHub project page. The WinPhone version will contain two extra labels. Not overly fancy, but educational enough.

First things first, I’ll add a simple view model:

public class AboutViewModel : BaseViewModel
{
    public AboutViewModel()
    {
        OpenUrlCommand = new Command<string>(s => Device.OpenUri(new Uri(s)));
    }
 
    public string BlogUrl { get { return @"http://blog.masterdevs.com/xf-day-10/"; } }
 
    public string CodeUrl { get { return @"https://github.com/jquintus/spikes/tree/master/XamarinSpikes/ShoppingCart"; } }
 
    public ICommand OpenUrlCommand { get; private set; }
}

The only thing remotely interesting here is the Device.OpenUri(…) call. It does pretty much what you expect it to, namely opens the URI in the native browser. This view model is so simple that I don’t even really need to inherit from BaseViewModel. I do anyway just to future proof it and for consistency.

Next thing I need to do is add the AboutPage stub in in the core project (ShoppingCart.csproj). For reasons I’ll go into a bit later, this can’t be defined in Xaml.

namespace ShoppingCart.Views
{
    public class AboutPage : ContentPage
    {
        public AboutPage()
        {
            Title = "About";
            Content = new Label { Text = "This page is not available for your platform", }; 
        }
    }
}

Nice and simple. Just set the title and get out of there.

Now all I need to do is wire up a button somewhere to navigate me to this page. I already have an action bar and app bar on the main CategoriesListPage, so I’ll just add another button there.

<ContentPage.ToolbarItems>
  <ToolbarItem Name="Log Out" Command="{Binding LogOut}"  Order="Primary" Priority="0">
    <ToolbarItem.Icon>
      <OnPlatform x:TypeArguments="FileImageSource"
                  WinPhone="Assets/Logout.png"
                  Android="ic_action_logout.png" />
    </ToolbarItem.Icon>
  </ToolbarItem>
 
  <ToolbarItem Name="About"
               Command="{Binding AboutCommand}" 
               Order="Secondary"
               Priority="0"/>
</ContentPage.ToolbarItems>

I don’t bother with an icon, so I put it in the “Secondary” order. On WinPhone and Droid this means it will only show up win you hit the three dots to expand the menu. It’s bound to the “AboutCommand” which just uses the existing navigation system to take you to the AboutPage.

WinPhone

The first step to getting a native page shown is to define a native page. So here’s the Xaml for my WinPhoneAboutPage.

<phone:PhoneApplicationPage
    x:Class="ShoppingCart.WinPhone.Views.WinPhoneAboutPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">
 
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
 
        <StackPanel Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="Shopping Cart"
                       Style="{StaticResource PhoneTextNormalStyle}"
                       Foreground="{StaticResource PhoneAccentBrush}" />
            <TextBlock Text="about" Margin="9,-7,0,0"
                       Style="{StaticResource PhoneTextTitle1Style}"
                       Foreground="{StaticResource PhoneAccentBrush}" />
        </StackPanel>
 
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
 
            <Button Grid.Row="1" Content="Browse Source Code"
                    Command="{Binding OpenUrlCommand}"
                    CommandParameter="{Binding CodeUrl}" />
 
            <Button Grid.Row="3" Content="Read Blog"
                    Command="{Binding OpenUrlCommand}"
                    CommandParameter="{Binding BlogUrl}" />
        </Grid>
    </Grid>
</phone:PhoneApplicationPage>

A very standard view. The next thing I need to do is to set the DataContext of the page so my bindings actually work. I’m inclined to follow the MvvmLight model with the ServiceLocator, but in all honesty that seems like a lot of ceremony for what I know will be one instance of a native view in this app. So, I cheat a little a bit and just manually set the context in the code behind:

public partial class WinPhoneAboutPage : PhoneApplicationPage
{
    public WinPhoneAboutPage()
    {
        this.DataContext = ShoppingCart.App.AboutViewModel;
        InitializeComponent();
    }
}

Now to wire it up I’ll add a PageRenderer:

public class WinPhoneAboutPageRenderer :  Xamarin.Forms.Platform.WinPhone.PageRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);
        this.Children.Add(new AboutPage());
    }
}

And now that we have the PageRenderer defined, we need to tell the system to actually use it:

[assembly: ExportRenderer(typeof(ShoppingCart.Views.AboutPage), 
                          typeof(ShoppingCart.WinPhone.Views.WinPhoneAboutPageRenderer))]

This line can go anywhere in the assembly (just not within a namespace). A lot of the examples place it in the same file as the renderer. This has the benefit of keeping it close to where we’re using it. I’ve elected to add this line at the beginning of the WinPhoneSetup file. If we wind up with several definitions for renderers, it would be nice to have them all in one place. I could be wrong about this.

Firing up the emulator and this looks… more than a little wrong.

So, on my fist pass of the ShoppingCart.AboutPage, I had added a label and two buttons. When the WinPhoneAboutPageRenderer created the WinPhoneAboutPage, it just overlaid it on top of the existing controls. Ok, so what if we add a call to Children.Clear()? This still doesn’t look right, and to show exactly what’s wrong, I’ve added a splash of color to the page.

I set the background color of the entire page to red, and of the grid with my buttons to a light green. As you can see, it’s not exactly taking up the entire page.

Children.Add doesn’t seem to be working for me at all, so I’ll try calling SetNativeControl. The problem here is that since I’ve inherited from PageRenderer it expects a Xamarin.Forms.Page and I have a Microsoft.Phone.Controls.PhoneApplicationPage. So I need to change what I’m inheriting from.

public class WinPhoneAboutPageRenderer 
  : VisualElementRenderer<Xamarin.Forms.Page, 
                          Microsoft.Phone.Controls.PhoneApplicationPage>
{
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);
        SetNativeControl(new WinPhoneAboutPage());
    }
}

Now that I’m inheriting from the VisualElementRenderer (the base class for the PageRenderer), I can specify that the object I’ll specify to replace the Xamarin.Forms.Page will be a WinPhone page. Now it’s a simple matter of passing SetNativeControl a new instance of my WinPhoneAboutPage. This winds up looking like what I want.

Droid About Page

Moving on to Droid, I create an xml file defining my layout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <View
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:layout_weight="1" />
    <Button
        android:id="@+id/button_blog"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Read Blog" />
    <View
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:layout_weight="1" />
    <Button
        android:id="@+id/button_code"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Browse Code" />
    <View
        android:layout_height="0dp"
        android:layout_width="fill_parent"
        android:layout_weight="1" />
</LinearLayout>

Again, simple two buttons. The views are just there as spacers.

And pretty much straight from the samples, here’s my renderer:

public class DroidAboutPageRenderer : PageRenderer
{
    private Android.Views.View _view;
 
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
    {
        base.OnElementChanged(e);
 
        AboutViewModel viewModel = App.AboutViewModel;
        var activity = this.Context as Activity;
        _view = activity.LayoutInflater.Inflate(Resource.Layout.AboutLayout, this, false);
 
        var blogButton = _view.FindViewById<Button>(Resource.Id.button_blog);
        var codeButton = _view.FindViewById<Button>(Resource.Id.button_code);
 
        blogButton.Click += (sender, ev) => viewModel.OpenUrlCommand.Execute(viewModel.BlogUrl);
        codeButton.Click += (sender, ev) => viewModel.OpenUrlCommand.Execute(viewModel.CodeUrl);
        AddView(_view);
    }
 
    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        base.OnLayout(changed, l, t, r, b);
        var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
        var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);
        _view.Measure(msw, msh);
        _view.Layout(0, 0, r - l, b - t);
    }
}

First things first, I grab the view model from my static cache. Then I just inflate my view, and start grabbing my buttons so I can add click handlers. Android doesn’t have a concept of data binding, so adding click handlers is a tad manual. Once everything is wired up, I add my view to the renderer. And now I have some errors.

I/MonoDroid( 1596): UNHANDLED EXCEPTION: System.InvalidOperationException: SetElement did not create the correct number of children
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[Xamarin.Forms.Page].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[Xamarin.Forms.Page].SetElement (Xamarin.Forms.Page element) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[Xamarin.Forms.Page].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.RendererFactory.GetRenderer (Xamarin.Forms.VisualElement view) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.NavigationRenderer.SwitchContentAsync (Xamarin.Forms.Page view, Boolean animated, Boolean removed) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.NavigationRenderer.OnPushAsync (Xamarin.Forms.Page view, Boolean animated) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.NavigationRenderer.PushViewAsync (Xamarin.Forms.Page page, Boolean animated) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.Platform.Android.NavigationRenderer.OnPushed (System.Object sender, Xamarin.Forms.NavigationRequestedEventArgs e) [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at Xamarin.Forms.NavigationPage+<PushAsync>d__c.MoveNext () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596): --- End of stack trace from previous location where exception was thrown ---
I/MonoDroid( 1596):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at ShoppingCart.Services.AppNavigation+<ShowAbout>d__4.MoveNext () [0x0001e] in c:\code\Repos\spikes\XamarinSpikes\ShoppingCart\ShoppingCart\ShoppingCart\Services\AppNavigation.cs:35 
I/MonoDroid( 1596): --- End of stack trace from previous location where exception was thrown ---
I/MonoDroid( 1596):   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <filename unknown>:0 
I/MonoDroid( 1596):   at ShoppingCart.ViewModels.CategoriesListViewModel+ctor>b__2>d__a.MoveNext () [0x0001b] in c:\code\Repos\spikes\XamarinSpikes\ShoppingCart\ShoppingCart\ShoppingCart\ViewModels\CategoriesListViewModel.cs:39 

The stack trace doesn’t say it, but this error is raised when you call AddView if the ShoppingCart.AboutPage has already had the Content property set. So, I go back to the AboutPage, and pull out the Content property:

namespace ShoppingCart.Views
{
    public class AboutPage : ContentPage
    {
        public AboutPage()
        {
            Title = "About";
        }
    }
}

Back to the DroidAboutPageRenderer, the OnLayout override is there to make sure that the view is sized to fit the whole screen. From the top left (0, 0) to the very bottom right (r-l, b-t).

Don’t forget to register it. Again, I decided to add this to the top of DroidSetup.cs.

[assembly: ExportRenderer(typeof(ShoppingCart.Views.AboutPage), 
                          typeof(ShoppingCart.Droid.Renderers.DroidAboutPageRenderer))]

Running this up, we get a wonderful (if not pretty) native layout:

iOS About Page (A Default)

Don’t get too excited. I still don’t have access to an iDevice. But I wanted to at least try and make sure that the app wouldn’t crash on iOS. I’ve updated the core definition of the AboutPage to at least show a label explaining that this page wasn’t available.

public class AboutPage : ContentPage
{
    public AboutPage()
    {
        Title = "About";
 
        if (Device.OS != TargetPlatform.Android)
        {
            Content = new Label
            {
                Text = "This page is not available for your platform",
            };
        }
    }
}

Since we saw that Android get’s really upset if you set the content in the core version of the page and then try to use a PageRenderer in the platform (at least with my implementation of the renderer), I make sure that we aren’t running on an Android device before setting the content. The content could have been set to something much more complicated than just a simple label. It could have even used data bindings like any other page.

Since I don’t have an iPhone, here’s what it looks like on a Droid.

And now we have native views on 2 out of 3 platforms.

Happy Coding

this post was originally on the MasterDevs Blog

To recap, I’m writing a shopping cart app for Windows Phone, Android, and iOS. The purpose of the app is primarily to let me use Forms. Each post will build on top of the previous one.

Last time I wrote data to disk. This week I’m going to add an application level menu.

Reminder, this article is a direct continuation of last week’s article. The code base is entirely the same. The posts were split up so that neither would be too long. For consistency’s sake, I have created separate releases for each week.

Recap and Code

This is the ninth post in the series, you can find the rest here:

  • Day 0: Getting Started (blog / code)
  • Day 1: Binding and Navigation (blog / code)
  • Day 2: Frames, Event Handlers, and Binding Bugs (blog / code)
  • Day 3: Images in Lists (blog / code)
  • Day 4: Search and Barcode Scanner (blog / code)
  • Day 5: Dependency Injection (blog / code)
  • Day 6: Styling (blog / code)
  • Day 7: Attached Behaviors (blog / code)
  • Day 8: Writing to Disk (blog / code)
  • Day 9: App and Action Bars (blog / code)
  • Day 10: Native Views (blog / code)

For a full index of posts, including future posts, go to the GitHub project page.

Logging Out

Now that I’m all logged in, I need to be able to log out. Ideally this would go in a dedicated page with various settings. But honestly, that’d be boring. This app already has plenty of pages. What it doesn’t have is a system level menu — an Action Bar on Droid or an App Bar on Windows Phone.

Adding the menu is rather straight forward, just some simple XAML and bindings to CategoriesListPage.xaml:

<ContentPage.ToolbarItems>
  <ToolbarItem Name="Log Out" Command="{Binding LogOut}" Order="Primary" Priority="0">
    <ToolbarItem.Icon>
      <OnPlatform x:TypeArguments="FileImageSource"
                  WinPhone="Assets/Logout.png"
                  Android="ic_action_logout.png" />
    </ToolbarItem.Icon>
  </ToolbarItem>
</ContentPage.ToolbarItems>

Conveniently, ToolbarItem has a Command property that you can bind against to handle clicks. The command binds the same as a button. The icon is a bit more involved.

Now the question is: where can I get good icons for my app? This leads me to a quick aside…

Windows Phone Icons

The easiest way to get icons for a Windows Phone or Metro-style Windows apps is to use Metro Studio by Syncfusion. First off, it’s free. Second off, it’s full of great icons. Just search for whatever you want, and then customize it for your uses. You can even create icons out of text in whatever font you like. Finally, a use for Wingdings.

Android Icons

Metro Studio packs a lot of punch, but doesn’t offer any help for Android apps (kinda makes sense given the name). For Android assets, check out the Android Asset Studio. There’s a lot of good stuff in here, but for this project I went straight to the Action Bar and Tab Icons section. They provide a library of images (although significantly smaller than Metro Studio), the ability to upload an image of your choice, or to enter an arbitrary string (and we still get Wingdings!). The best part is that it generates a zip with assets for various screen resolutions. Just unzip and drop the folders into the Resources directory.

Image Asset Locations

<ToolbarItem.Icon>
  <OnPlatform x:TypeArguments="FileImageSource"
              WinPhone="Assets/Logout.png"
              Android="ic_action_logout.png" />
</ToolbarItem.Icon>

Because I’m specifying the location of the icon as a string, I need to make sure that the images are placed in the correct locations in the corresponding project folders. The XF documentation explains pretty clearly where each goes.

For my WinPhone project, I place the Logout.png in the “Assets” folder.

Android is a little bit more complicated since the platform allows you to serve different sized images for devices with different resolutions. Each file is put in the corresponding drawable folder under “Resources”. As I said earlier, the Android Asset Studio does all this for you. You can just drop the folders it generates directly into the Resources folder.

Doing Async Work at Startup

Previously, when the app started up it went directly to the login screen. Now it has to first check to see if the user is logged in. If they are then the app goes to the categories page, otherwise it goes to the login page. This is easy, except for the fact that the check happens on the background thread and takes some time since it is going to disk. Not a lot of time, but enough that we aren’t guaranteed to get the result back before the app is ready to start up. In order to accommodate this, I’m turning the “WelcomePage” into a splash page. It will display a progress dialog for a little bit and then navigate to the next page once it knows which page that is. Let’s start with the view:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ShoppingCart.Views.WelcomePage"
             xmlns:local="clr-namespace:ShoppingCart;assembly=ShoppingCart"
             BindingContext="{x:Static local:App.WelcomeViewModel}"
             BackgroundColor="White">
 
  <StackLayout VerticalOptions="Center"
               IsVisible="{Binding IsLoaded, Mode=OneWayToSource}">
    <Frame>
      <Label Text="Welcome to The Store"
             Font="Bold, Large"
             HorizontalOptions="Center"
             TextColor="{x:Static local:App.AccentColor}" />
    </Frame>
 
    <ActivityIndicator IsRunning="{Binding IsBusy.IsNotCompleted}"
                       HorizontalOptions="FillAndExpand"
                       VerticalOptions="FillAndExpand"
                       Color="{x:Static local:App.AccentColor}" />
  </StackLayout>
</ContentPage>

The ActivityIndicator starting on line 18 is pretty straight forward. I bind whether or not it is running to the NotifyTaskCompletion property on the view model (more on that later), and the color to the static representation of the accent color in the same way that I do for the label. You should remember this from the styling article from a couple of weeks ago.

A little more interesting is the one way to source binding on the visibility of the stack layout. This is here to tell the view model that the view has been displayed. Since this is the first page in the XF app it is wrapped in the NavigationPage, which initializes the NavigationService. If we try to navigate away from this view before it is shown, we have no navigation service, and so navigation won’t work. Classic Catch-22.

public class WelcomeViewModel : BaseViewModel
{
    private readonly IAppNavigation _navi;
    private SemaphoreSlim _slim;
 
    public WelcomeViewModel(IAppNavigation navi)
    {
        _navi = navi;
        _slim = new SemaphoreSlim(0, 1);
        IsBusy = new NotifyTaskCompletion<int>(GoToFirstPage());
    }
 
    public NotifyTaskCompletion<int> IsBusy { get; private set; }
 
    public bool IsLoaded
    {
        get { return GetValue<bool>(); }
        set
        {
            SetValue(value);
            if (value)
            {
                _slim.Release();
            }
        }
    }
 
    private async Task<int> GoToFirstPage()
    {
        await _slim.WaitAsync();
        await _navi.SecondPage();
        return 0;
    }
}

The first thing the view model does is initialize a SemaphoreSlim in the unsignaled state, i.e., calling Wait() will block. It then creates a NotifyTaskCompletion of type int. Creating this kicks off the async call to GoToFirstPage. The return value doesn’t matter in this case, the object is just being used to run a background task and update the UI with the status.

When IsLoaded is set to true by the binding to the visibility of the StackLayout in the view, it signals the semaphore, allowing the WaitAsync in GoToFirstPage to complete. GoToFirstPage then tells the navigation service to show the second page in the app. The navigation service handles the logic of determining which page to show as well as actually navigating to the page. For the sake of demonstration, I’ve added a delay in the video below.

Here’s what the app looks like when the user needs to log in

And here’s what the returning a user sees

Happy Coding

this post was originally on the MasterDevs Blog

To recap, I’m writing a shopping cart app for Windows Phone, Android, and iOS. The purpose of the app is primarily to let me use Forms. Each post will build on top of the previous one.

Last time I added behaviors to my XF xaml. This week I’m going to save settings to disk using Akavache.

Once I started writing the post to go along with this week’s post, I quickly became aware that the it was longer than what really makes sense for a single post. So I’m splitting the article in two. This week will be logging in, next week will be logging out. Both weeks will use the same code. For consistency’s sake, I’ll be creating a new release for next week, even though it will point to the same code.

Recap and Code This is the eight post in the series, you can find the rest here:

  • Day 0: Getting Started (blog / code)
  • Day 1: Binding and Navigation (blog / code)
  • Day 2: Frames, Event Handlers, and Binding Bugs (blog / code)
  • Day 3: Images in Lists (blog / code)
  • Day 4: Search and Barcode Scanner (blog / code)
  • Day 5: Dependency Injection (blog / code)
  • Day 6: Styling (blog / code)
  • Day 7: Attached Behaviors (blog / code)
  • Day 8: Writing to Disk (blog / code)
  • Day 9: App and Action Bars (blog / code)
  • Day 10: Native Views (blog / code)

For a full index of posts, including future posts, go to the GitHub project page.

Installing Akavache Cheat Sheet

At the risk of spoiling the narrative below, here’s a very brief outline of the steps to install and use Akavache in a Xamarin Forms app. For links and more details, continue reading.

  1. Install Akavache package in common PCL project (Install-Package akavache)
  2. Install Akavache package in platform specific projects
    1. Droid
    2. Win Phone
    3. iOS (The iOS step is assumed to be necessary and sufficient to make Akavache work, but I am unable to verify it)
  3. WinPhone: Update Splat package (Update-Package splat)
  4. WinPhone: Change build configuration to x86

Logging In

From the beginning one of the things that really bothered me about this app is that I have to log in each time I use it. And that’s including the fact that I don’t have to type in a particular username/password. Any text will do. I guess I’m just lazy.

To persist logging in, I’m just going to write a little bit of information to disk when I’m logging in for the first time. Next time I open the app, I’ll just check for that value, if it exists I’ll go straight to the main landing page.

I don’t want to tie my implementation down to an unknown framework, so the first thing I need to do is create an interface to abstract away persisting data:

public interface ICache
{
    Task<T> GetObject<T>(string key);
    Task InsertObject<T>(string key, T value);
    Task RemoveObject(string key);
}

This interface should handle all of my CRUD operations. Right now the only person that needs to use it is my LoginService.

public async Task<User> LoginAsync(string username, string password)
{
    User user = Login(username, password);
 
    await _cache.InsertObject("LOGIN", user);
 
    return user;
}
 
public async Task<bool> IsLoggedIn()
{
    User user = await _cache.GetObject<User>("LOGIN");
    return user != null;
}

LoginAsync performs the standard log in check, verifying that username and password are valid credentials (in reality it just checks that they are non-null) and returns a user object if they are valid. I then save that in the cache using “LOGIN” as the key. Next, IsLoggedIn in checks to see if there is a non-null value stored in the cache.

Now that we know how the cache is going to be used, let’s implement it.

Akavache

I’ll be using Akavache as my data store. It’s probably a bit overkill for the very simple use case I have but I have a few reasons why I want to use it. First, I really don’t want to think about where exactly I’m storing this data. It could be in a database, it could be on disk, my app doesn’t really care. It’s just a set of keys and values to me. While Akavache does use a SQLite backend, I don’t have to know any of the details. I’m also looking for something that is async/await friendly. Akavache supports many platforms, I’d love to be able to write this once for all platforms. And finally, I recently heard about it and kind of wanted to play with it.

Here’s a summary of what I just stated above as my reasons for using Akavache

  • Abstract away storage details
  • async API
  • Cross platform
  • It’s new to me

Akavache on Droid

Akavache is a nuget package, so installation is easy. I’m installing the package into the core project (ShoppingCart.csproj). For it to work it also needs to be installed on the Droid project as well. In my Services folder I’ll add my Akavache implementation of ICache. This class will be used by all of the platforms.

using Akavache;
using ShoppingCart.Services;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading.Tasks;
 
namespace ShoppingCart.Services
{
    public class Cache : ICache
    {
        public Cache()
        {
            BlobCache.ApplicationName = "ShoppingCart";
        }
 
        public async Task RemoveObject(string key)
        {
            await BlobCache.LocalMachine.Invalidate(key);
        }
 
        public async Task<T> GetObject<T>(string key)
        {
            try
            {
                return await BlobCache.LocalMachine.GetObject<T>(key);
            }
            catch (KeyNotFoundException)
            {
                return default(T);
            }
        }
 
        public async Task InsertObject<T>(string key, T value)
        {
            await BlobCache.LocalMachine.InsertObject(key, value);
        }
    }
}

First thing to note here is that I’m importing the System.Reactive.Linq namespace. This enables us to await the Akavache calls. Next thing to note is that I’m setting the ApplicationName property in the constructor. This is needed to initialize storage. The rest of the implementation is pretty straight forward. You can even see that I got most of my method names from the Akavache API.

The RemoveObject implementation invalidates the object in Akavache. GetObject tries to read the object from the cache, catching any KeyNotFoundExceptions.

Next week I’ll go over how all of this gets plugged into the UI.

Akavache on Win Phone

Akavache is a bit more fiddly on Win Phone.

To start off, install the Akavache nuget package directly in the Win Phone project. Remember, it’s already installed in my PCL project where it is being used, it needs to be installed here as well, even though none of the code reference it directly. At this point, I get my first error:

System.TypeInitializationException was unhandled by user code
  HResult=-2146233036
  Message=The type initializer for 'Akavache.BlobCache' threw an exception.
  Source=Akavache
  TypeName=Akavache.BlobCache
  StackTrace:
       at Akavache.BlobCache.set_ApplicationName(String value)
       at ShoppingCart.WinPhone.Services.WinPhoneCache..ctor()
       at lambda_method(Closure , Object[] )
       at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
  InnerException: System.IO.FileLoadException
       HResult=-2146234304
       Message=Could not load file or assembly 'Splat, Version=1.4.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
       Source=Akavache
       StackTrace:
            at Akavache.BlobCache..cctor()
       InnerException:

There is an assembly that can’t be found. Splat is a another package produced by Paul Betts (the producer of Akavache). The problem here is not that the file isn’t there, but that it’s an older version. All I need to do is update the nuget package for Splat and I’m good.

Updating Splat

With this resolved, the next exception I get is that correct version of SQLitePcl.Raw is missing.

System.TypeInitializationException was unhandled by user code
  HResult=-2146233036
  Message=The type initializer for 'Akavache.Sqlite3.Internal.SQLiteConnection' threw an exception.
  Source=Akavache.Sqlite3
  TypeName=Akavache.Sqlite3.Internal.SQLiteConnection
  StackTrace:
       at Akavache.Sqlite3.Internal.SQLiteConnection..ctor(String databasePath, Boolean storeDateTimeAsTicks)
       at Akavache.Sqlite3.SQLitePersistentBlobCache..ctor(String databaseFile, IScheduler scheduler)
       at Akavache.Sqlite3.Registrations.<>c__DisplayClass6.<Register>b__2()
       at System.Lazy`1.CreateValue()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Lazy`1.get_Value()
       at Akavache.Sqlite3.Registrations.<>c__DisplayClass6.<Register>b__3()
       at Splat.ModernDependencyResolver.GetService(Type serviceType, String contract)
       at Splat.DependencyResolverMixins.GetService[T](IDependencyResolver This, String contract)
       at Akavache.BlobCache.get_UserAccount()
       at ShoppingCart.Services.LoginService.get_Users()
       at ShoppingCart.Services.LoginService.<LoginAsync>d__4.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at ShoppingCart.ViewModels.LoginViewModel.<Login>d__0.MoveNext()
  InnerException: System.IO.FileNotFoundException
       HResult=-2147024894
       Message=Could not load file or assembly 'SQLitePCL.raw, Version=0.5.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
       Source=Akavache.Sqlite3
       FileName=SQLitePCL.raw, Version=0.5.0.0, Culture=neutral, PublicKeyToken=null
       StackTrace:
            at Akavache.Sqlite3.Internal.SQLiteConnection..cctor()
       InnerException:

Again this is a nuget package, but this time updating does not fix the problem. I reached out to Paul about the issue and he told me that I have to change the build configuration of the Win Phone project to specify x86 as my platform.

Open Configuraton Manager

Configuraton Manager

Now running the app will work.

Thanks

A big thanks to Paul Betts both for writing Akavache and for providing the last mile of help when I needed it.

Happy Coding

this post was originally on the MasterDevs Blog

I just had the need to style the search box in the actionbar of my Xamarin Android application. For those of you who don’t know, Xamarin lets you write native Android apps in .Net, specifically C#.

Here’s the search box before styling:

Here’s the look I was going for:

I was using ActionBarSherlock to create the actionbar. After searching for a while, I came to the conclusion that the only way to customize the actionbar using the Android style system was to switch to AppCompat. So now the steps seem pretty clear and easy:

Migrate from ActionBarSherlock to AppCompat Create a style for my search box Apply style in just the right place. I ran into more bumps along the way than expected, so I wanted to write down exactly what I had to do to get this working.

Migrating to from Sherlock to AppCompat

Before really considering using AppCompat, I checked to see how well it was supported by Xamarin and found a useful post on their blog with some sample code. This looked promising and I was able to get it to compile locally, so full steam ahead. Back in my project, I deleted the ActionBarSherlock Xamarin component and added in the AppCompat component. I then walked through my code changing all code referencing Sherlock to AppCompat. Wolram Rittmeyer has an excellent post on the step by step process to do this.

My first concern was that I also use MvvmCross, which requires that all Activity classes implement IMvxEventSourceActivity and IMvxAndroidView. So months ago (almost a year ago according to my commit history) I created the MvxActionBarSherlockFragmentActivity base class that inherits from SherlockFragmentActivity and implements the MvvmCross interfaces. Not remembering what went into creating the class I was concerned it would be tedious to replace it with an AppCompat version. Turns out it was trivial. All I had to do was inhert from ActionBarActivity instead. It was literally a one word change. Here’s my new MvxActionBarActivity:

using Android.App;
using Android.Content;
using Android.OS;
using Android.Support.V7.App;
using Cirrious.CrossCore.Core;
using Cirrious.CrossCore.Droid.Views;
using Cirrious.MvvmCross.Binding.BindingContext;
using Cirrious.MvvmCross.Binding.Droid.BindingContext;
using Cirrious.MvvmCross.Droid.Views;
using Cirrious.MvvmCross.ViewModels;
using System;
 
namespace Masterdevs.Droid.Views
{
    public class MvxActionBarActivity : ActionBarActivity, IMvxEventSourceActivity, IMvxAndroidView
    {
        protected MvxActionBarActivity()
        {
            BindingContext = new MvxAndroidBindingContext(this, this);
            this.AddEventListeners();
        }
 
        public event EventHandler<MvxValueEventArgs<MvxActivityResultParameters>> ActivityResultCalled;
        public event EventHandler<MvxValueEventArgs<Bundle>> CreateCalled;
        public event EventHandler<MvxValueEventArgs<Bundle>> CreateWillBeCalled;
        public event EventHandler DestroyCalled;
        public event EventHandler DisposeCalled;
        public event EventHandler<MvxValueEventArgs<Intent>> NewIntentCalled;
        public event EventHandler PauseCalled;
        public event EventHandler RestartCalled;
        public event EventHandler ResumeCalled;
        public event EventHandler<MvxValueEventArgs<Bundle>> SaveInstanceStateCalled;
        public event EventHandler<MvxValueEventArgs<MvxStartActivityForResultParameters>> StartActivityForResultCalled;
        public event EventHandler StartCalled;
        public event EventHandler StopCalled;
 
        public IMvxBindingContext BindingContext { get; set; }
 
        public object DataContext
        {
            get { return BindingContext.DataContext; }
            set { BindingContext.DataContext = value; }
        }
 
        public IMvxViewModel ViewModel
        {
            get { return DataContext as IMvxViewModel; }
            set
            {
                DataContext = value;
                OnViewModelSet();
            }
        }
 
        public void MvxInternalStartActivityForResult(Intent intent, int requestCode)
        {
            base.StartActivityForResult(intent, requestCode);
        }
 
        public override void SetContentView(int layoutResId)
        {
#if DEBUG // This try catch is super useful when debugging bad layouts.  No real need for it in prod.
            try
            {
#endif
                var view = this.BindingInflate(layoutResId, null);
                SetContentView(view);
#if DEBUG
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);  // Because of the JNI layers, this is the easiest way to reliably get the message from the exception when debugging.  The watch window isn't as reliable/timely
                throw;
            }
#endif
        }
 
        public override void StartActivityForResult(Intent intent, int requestCode)
        {
            StartActivityForResultCalled.Raise(this, new MvxStartActivityForResultParameters(intent, requestCode));
            base.StartActivityForResult(intent, requestCode);
        }
 
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                DisposeCalled.Raise(this);
            }
            base.Dispose(disposing);
        }
 
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            ActivityResultCalled.Raise(this, new MvxActivityResultParameters(requestCode, resultCode, data));
            base.OnActivityResult(requestCode, resultCode, data);
        }
 
        protected override void OnCreate(Bundle bundle)
        {
            CreateWillBeCalled.Raise(this, bundle);
            base.OnCreate(bundle);
            CreateCalled.Raise(this, bundle);
        }
 
        protected override void OnDestroy()
        {
            DestroyCalled.Raise(this);
            base.OnDestroy();
        }
 
        protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);
            NewIntentCalled.Raise(this, intent);
        }
 
        protected override void OnPause()
        {
            PauseCalled.Raise(this);
            base.OnPause();
        }
 
        protected override void OnRestart()
        {
            base.OnRestart();
            RestartCalled.Raise(this);
        }
 
        protected override void OnResume()
        {
            base.OnResume();
            ResumeCalled.Raise(this);
        }
 
        protected override void OnSaveInstanceState(Bundle outState)
        {
            SaveInstanceStateCalled.Raise(this, outState);
            base.OnSaveInstanceState(outState);
        }
 
        protected override void OnStart()
        {
            base.OnStart();
            StartCalled.Raise(this);
        }
 
        protected override void OnStop()
        {
            StopCalled.Raise(this);
            base.OnStop();
        }
 
        protected virtual void OnViewModelSet()
        {
        }
    }
}

With that done, all my MvvmCross worries were over and my app should compile. Not quite. On either score. It turns out that the version of MvvmCross I was using was referencing the old Mono.Android.Support.v4.dll while the AppCompat library referenced the new Xamarin.Android.Support.v4.dll. These are essentially the same library, but with different names. There is an excellent summary on Xamarin’s bugzilla. Finally after carefully reading through all of the bug report, at the very bottom, I found Stuart’s comment saying that he’d already released a fixed version. All I had to do was update to the latest version of MvvmCross in NuGet. And now my code actually compiled and my MvvmCross concerns were over.

Fixing the Null SearchView

While my code happily compiled, it wasn’t quite as happy about actually running.

public override bool OnCreateOptionsMenu(IMenu menu)
{
    MenuInflater.Inflate(Resource.Menu.ManageUsers, menu);
    var searchItem = menu.FindItem(Resource.Id.action_search);
 
    var view = MenuItemCompat.GetActionView(searchItem);
    var searchView = view.JavaCast<Android.Support.V7.Widget.SearchView>();
 
    searchView.QueryTextChange += (s, e) => ViewModel.Filter = e.NewText;
 
    return base.OnCreateOptionsMenu(menu);
}

Whenever I tried to get the action view from the search menu item, it was null. My first instinct was to double check my menu definition:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto" >
  <item android:id="@+id/action_search"
        android:title="Search Friends"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="ifRoom|collapseActionView"
        app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

It looked right. I had remembered to use the AppCompat search view. After some digging on the inter-tubes, I found a post on StackOverflow explaining that my themes had to specifically derive from AppCompat themes. Ok, so a trip to the style generatorand I’m using the correct themes.

So now it’s been a while, and I have a lot of checked out code. But I’ve finally gotten back to where I was when I started. An app that compiles, runs, and has an ugly search box.

The trick, (thanks to Andreas Nilsson for explaining it) is to set your own style searchViewAutoCompleteTextView in the Theme.AppCompat style.

<resources>
    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
        <item name="android:actionBarWidgetTheme">@style/ActionBarWidget.actionbar</item>
    </style>
 
    <style name="ActionBarWidget.actionbar" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="searchViewAutoCompleteTextView">@style/AutoCompleteTextView.actionbar</item>
    </style>
 
    <style name="AutoCompleteTextView.actionbar" parent="Widget.AppCompat.Light.AutoCompleteTextView">
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textCursorDrawable">@null</item>
    </style>
</resources>

Thanks and Resources

Thanks to Wolfram Rittmeyer for his methodical description on how to migrate from Sherlock to AppCompat. Another thanks to Andreas Nilsson for his blog post showing that it was even possible to customize the the search box using styles. I encourage you to read both blog posts, since they go into far greater detail.

Happy Coding.

this post was originally on the MasterDevs Blog

To recap, I’m writing a shopping cart app for Windows Phone, Android, and iOS. The purpose of the app is primarily to let me use Forms. Each post will build on top of the previous one.

Last time I styled the app so it looked slick. This week I am going to revisit a problem I had in my Day 2 post, namely the lack of an EventToCommand behavior. A developer named Corrado created a Behaviors library specifically for Xamarin.Forms. This library comes with an EventToCommand behavior out of the box, and lets you create your own.

Recap and Code

This is the seventh post in the series, you can find the rest here:

  • Day 0: Getting Started (blog / code)
  • Day 1: Binding and Navigation (blog / code)
  • Day 2: Frames, Event Handlers, and Binding Bugs (blog / code)
  • Day 3: Images in Lists (blog / code)
  • Day 4: Search and Barcode Scanner (blog / code)
  • Day 5: Dependency Injection (blog / code)
  • Day 6: Styling (blog / code)
  • Day 7: Attached Behaviors (blog / code)
  • Day 8: Writing to Disk (blog / code)
  • Day 9: App and Action Bars (blog / code)
  • Day 10: Native Views (blog / code)

For a full index of posts, including future posts, go to the GitHub project page.

Getting Behaviors

First off, you can check out Corrado’s own blog post about this library. You can also take a look at his code on GitHub, or just grab the library from nuget.

The first thing I did was install the nuget package in my core project (ShoppingCart). I did two things wrong here. First, there are two nuget packages to choose from: Xamarin.Behaviors and Xamarin.Forms.Behaviors. Unintuitively, the correct one to choose is Xamarin.Behaviors. The next mistake I made was that I installed it in just the core project. When I ran up the solution, I saw this error immediately:

System.IO.FileNotFoundException was unhandled by user code
Message=Could not load file or assembly 'Xamarin.Behaviors, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

I realized that the platform projects also need to reference the package. Easy enough.

TL;DR

To install behaviors install the nuget package in your shared project as well as all platform projects:

PM> Install-Package Xamarin.Forms.Behaviors

Using Behaviors

My first use case for behaviors is to remove the ugly event to command code I have in my code behind. Here’s the xaml that I want to get rid of:

<ListView ItemsSource="{Binding Categories.Result}"
    IsGroupingEnabled="false"
    ItemSelected="OnItemSelected">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <Label Text="{Binding .}" />
      </ViewCell>
    </DataTemplate>
</ListView>

Specifically, I don’t want the ItemSelected property set to the OnItemSelcted method in the code behind file:

private void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    var param = e.SelectedItem as string;
    var command = ((CategoriesListViewModel)BindingContext).NavigateToCategory;
 
    if (command.CanExecute(param))
    {
        command.Execute(param);
    }
}

This method casts the context to the view model, grabs the command, casts the SelectedItem into a string to act as the parameter, checks to see if it can call execute, and then calls execute.

First things first, I delete the OnItemSelected method. Gone. No more. Next, I add an EventToCommand behavior in my xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ShoppingCart.Views.CategoriesListPage"
             xmlns:b="clr-namespace:Xamarin.Behaviors;assembly=Xamarin.Behaviors"
             xmlns:local="clr-namespace:ShoppingCart;assembly=ShoppingCart"
             BindingContext="{x:Static local:App.CategoriesListViewModel}"
             BackgroundColor="White">
  <ListView ItemsSource="{Binding Categories.Result}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <TextCell Text="{Binding Name}"
                  Detail="{Binding Count}">
          <b:Interaction.Behaviors>
            <b:BehaviorCollection>
              <b:EventToCommand EventName="Tapped"
                                Command="{Binding NavigateToCategory}"
                                CommandParameter="{Binding Category}" />
            </b:BehaviorCollection>
          </b:Interaction.Behaviors>
        </TextCell>
      </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

There’s a little more going on here than just the behavior, so I’ll explain that first. First off, on line 4, I add the reference to the Behaviors namespace. I also change the DataTemplate from the generic ViewCell to the TextCell. This is mostly just to simplify my layout and because I only recently learned about the TextCell after reading a recent blog on the Xamarin Newsletter. The TextCell lets you create a row in a ListView with a main text field, and a description underneath. I also just realized that the ViewCell and TextCell both already have Command and CommandParameter properties that I could have bound to directly. Evidently I don’t need behaviors for this at all. I’m still going to use behaviors, just so I can play with them a bit. But, if you want to see how to do this without behaviors, check out my list view in the ProductsListPage.

So, now that I have my TextCell, I can use the Interaction.Behaviors attached property and add an EventToCommand behavior. The EventToCommand maps an event on the UI control to an ICommand on the view model. In this case, when the Tapped event of the TextCell is raised, the NavigateToCategory command will be executed. But which NavigateToCategory command? Originally this command existed on the CategoriesListViewModel, but that was when we were in the code behind and our BindingContext was the CategoriesListViewModel. By the time our EventToCommand is created, we are in the DataTemplate and only have access to the individual members of Categories.Results which was originally a list of strings. If we were using WPF, we would have been able to bind to our parent’s context using RelativeSource binding and access the command. RelativeSource binding is not an option in XF. The easiest way around this for me is to change my categories list from strings to CategoryViewModels. Here’s my new view model:

public class CategoryViewModel : BaseViewModel
{
    private readonly Category _category;
 
    public CategoryViewModel(Category category, ICommand navigateCommand)
    {
        _category = category;
        Name = _category.Name;
 
        NavigateToCategory = navigateCommand;
    }
 
    public Category Category { get { return _category; } }
 
    public string Count { get; private set; }
 
    public string Name { get; private set; }
 
    public ICommand NavigateToCategory { get; private set; }
}

The CategoriesListViewModel creates these instances, and just passes the navigate command in. The implementation of the command itself isn’t changed. Truth be told, passing the command in like this is a bit of a hack. It would be cleaner to use the Message Center. That’s a bit out of the scope for this article, perhaps I’ll clean this up next week.

Another thing I’m doing that’s not strictly necessary, is passing in a CommandParameter. I’m just using it here just to show how it can be done. Currently, you can’t pass in the EventArgs as the parameter. There are times when that is useful, so hopefully it’s added some time in the future before I really need it.

What Did I Do Wrong?

Typo in the EventName

At one point in my testing, I had a typo in my EventToCommand where I was trying to bind to a nonexistent event.

<b:EventToCommand EventName="OnTapped"
                  Command="{Binding NavigateCommand}"
                  CommandParameter="{Binding Category}" />

OnTapped doesn’t exist. The correct event name is “Tapped”. This is the error you’ll see if/when you make that mistake:

System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list

The exception is confusing until you look at the EventToCommand code and see that there is a small bug in it when it is trying to throw what would be a much more helpful exception.

Typo in the Command

I also had some trouble with typos where I misspelled the name of the command. This was worse. It just silently doesn’t work. Typos are bad.

Creating Behaviors

Xamarin.Forms.Behaviors comes with two behaviors out of the box: EventToCommand which we discussed earlier, and TextChangedBehavior. Even better though, it gives you all the building blocks you need to create behaviors of your own. Suppose you want to have your Entry (text box) animate when you click in it. Something like this:

Windows Phone Animation

Droid Animation

Here’s the behavior that handles this:

using System;
using Xamarin.Behaviors;
using Xamarin.Forms;
 
namespace ShoppingCart.Behaviors
{
    public class AnimateSizeBehavior : Behavior<View>
    {
        public static readonly BindableProperty EasingFunctionProperty = BindableProperty.Create<AnimateSizeBehavior, string>(
            p => p.EasingFunctionName,
            "SinIn",
            propertyChanged: OnEasingFunctionChanged);
 
        public static readonly BindableProperty ScaleProperty = BindableProperty.Create<AnimateSizeBehavior, double>(
            p => p.Scale,
            1.25);
 
        private Easing _easingFunction;
 
        public string EasingFunctionName
        {
            get { return (string)GetValue(EasingFunctionProperty); }
            set { SetValue(EasingFunctionProperty, value); }
        }
 
        public double Scale
        {
            get { return (double)GetValue(ScaleProperty); }
            set { SetValue(ScaleProperty, value); }
        }
 
        protected override void OnAttach()
        {
            this.AssociatedObject.Focused += OnItemFocused;
        }
 
        protected override void OnDetach()
        {
            this.AssociatedObject.Focused -= OnItemFocused;
        }
 
        private static Easing GetEasing(string easingName)
        {
            switch (easingName)
            {
                case "BounceIn": return Easing.BounceIn;
                case "BounceOut": return Easing.BounceOut;
                case "CubicInOut": return Easing.CubicInOut;
                case "CubicOut": return Easing.CubicOut;
                case "Linear": return Easing.Linear;
                case "SinIn": return Easing.SinIn;
                case "SinInOut": return Easing.SinInOut;
                case "SinOut": return Easing.SinOut;
                case "SpringIn": return Easing.SpringIn;
                case "SpringOut": return Easing.SpringOut;
                default: throw new ArgumentException(easingName + " is not valid");
            }
        }
 
        private static void OnEasingFunctionChanged(BindableObject bindable, string oldvalue, string newvalue)
        {
            (bindable as AnimateSizeBehavior).EasingFunctionName = newvalue;
            (bindable as AnimateSizeBehavior)._easingFunction = GetEasing(newvalue);
        }
 
        private async void OnItemFocused(object sender, FocusEventArgs e)
        {
            await this.AssociatedObject.ScaleTo(Scale, 250, _easingFunction);
            await this.AssociatedObject.ScaleTo(1.00, 250, _easingFunction);
        }
    }
}

This is a big file, but not that much is really going on. AnimateSizeBehavior inherits from Behavior. This means that we can apply it to any type of control. It also means that the AssociatedObject property will be of type View. The key methods to look at are the OnAttach and OnDetach.

protected override void OnAttach()
{
    this.AssociatedObject.Focused += OnItemFocused;
}
 
protected override void OnDetach()
{
    this.AssociatedObject.Focused -= OnItemFocused;
}

OnAttach is called when the behavior is added to the the control and OnDetach is called when it is removed from the control. This is where I registered to receive the Focused event. Now it’s a simple matter that whenever the control gains focus my animation code in OnItemFocused will be called.

private async void OnItemFocused(object sender, FocusEventArgs e)
{
    await this.AssociatedObject.ScaleTo(Scale, 250, _easingFunction);
    await this.AssociatedObject.ScaleTo(1.00, 250, _easingFunction);
}

The animation is very straight forward. I use the ScaleTo method on View to scale the control up, then I call ScaleTo a second time to return it to its original size. If I didn’t want to provide any flexibility with my behavior, I could stop there. The rest of the code is just there to let me pass in parameters and configure how to perform the scale. Let’s look at Scale.

public static readonly BindableProperty ScaleProperty = BindableProperty.Create<AnimateSizeBehavior, double>(
    p => p.Scale,
    1.25,
    propertyChanged: OnScaleChanged);
 
public double Scale
{
    get { return (double)GetValue(ScaleProperty); }
    set { SetValue(ScaleProperty, value); }
}

First I set up a static BindableProperty called ScaleProperty. This is what lets me bind to properties on the behavior. The first parameter ties it to the double Scale instance property. The second parameter sets the default value to 1.25.

The EasingFunction property is a little more complicated. It requires validation when it is set. This is accomplished by setting the propertyChanged parameter in the factory method.

public static readonly BindableProperty EasingFunctionProperty = BindableProperty.Create<AnimateSizeBehavior, string>(
    p => p.EasingFunctionName,
    "SinIn",
    propertyChanged: OnEasingFunctionChanged);
 
private Easing _easingFunction;
 
public string EasingFunctionName
{
    get { return (string)GetValue(EasingFunctionProperty); }
    set { SetValue(EasingFunctionProperty, value); }
}
 
private static void OnEasingFunctionChanged(BindableObject bindable, string oldvalue, string newvalue)
{
    (bindable as AnimateSizeBehavior).EasingFunctionName = newvalue;
    (bindable as AnimateSizeBehavior)._easingFunction = GetEasing(newvalue);
}

The propertyChagned parameter is set to the static OnEasingFunctionChanged method. The instance of the behavior is passed in as the bindable parameter, along with the old and new values being set. In my example, we ignore the old value and just set the new value to the string property of EasingFunctionName. We also parse the new value to determine what type of easing function to use in the GetEasing method. If the easing function supplied is not an expected value, an exception is thrown. This happens not when we try to run the animation, but as soon as we set the value.

Now all I need to do is add the behavior to my text boxes. I’ll do this for the login page because there are two text boxes on the page so we can see how to tweak it.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:bLocal="clr-namespace:ShoppingCart.Behaviors;assembly=ShoppingCart"
             xmlns:b="clr-namespace:Xamarin.Behaviors;assembly=Xamarin.Behaviors"
             x:Class="ShoppingCart.Views.LoginPage" >
  <StackLayout VerticalOptions="FillAndExpand" Padding="50">
 
    <Entry Text ="{Binding Username}" Placeholder ="User name goes here" >
      <b:Interaction.Behaviors>
        <b:BehaviorCollection>
          <bLocal:AnimateSizeBehavior />
        </b:BehaviorCollection>
      </b:Interaction.Behaviors>
    </Entry>
 
    <Entry Text ="{Binding Password}"
      Placeholder ="Password goes here"
      HorizontalOptions="FillAndExpand">
      <b:Interaction.Behaviors>
        <b:BehaviorCollection>
          <bLocal:AnimateSizeBehavior EasingFunction="BounceIn"
                                      Scale="1.50" />
        </b:BehaviorCollection>
      </b:Interaction.Behaviors>
    </Entry>
 
  </StackLayout>
</ContentPage>

I stripped a lot out of the xaml here for clarity (like the submit button). The username textbox has the default behavior set. The password box changes the scale size to 1.5 and selects a different easing function. It would be possible to bind to those values as well, but it didn’t make sense in my already pointless example.

And that’s all there is to it. A quick thanks to lobrien for a useful sample on how to do animations in XF. This sped up my coding quite a bit. And of course a thanks to Corrado for the Xamarin.Forms.Behaviors library.

Happy Coding

this post was originally on the MasterDevs Blog