Xamarin

ContentPresenter for Xamarin.Forms

December 31, 2014 Coding 4 comments , ,

While working on a new Xamarin Forms project, I came across the need for a ContentPresenter ala Microsoft XAML. The basic idea is to use a placeholder for a piece of content (usually a ViewModel) and then supply a DataTemplate to control how it should be displayed.

A simple example might look like this:


<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <controls:ContentPresenter Grid.Row="1"
               BindingContext="{Binding MyModel, Source={StaticResource Locator}}" 
               ItemTemplate="{StaticResource MyModelTemplate}"
               />

</Grid>

This goes back to some of the more “classic” MVVM patterns where we want to make our display more componentized.

In Xamarin Forms Today (v1.3.0), if you want to create a custom component, you can derive from ContentView and go to town. Add your widgets either with XAML or in code. Many times though, we don’t really need to create a new class/view directly. A DataTemplate is sufficient as we can bind to the ViewModel and use Commands to take action. These are the so-called “zero code-behind” views.

In this case, a ContentPresenter is all we need – set the BindingContext to your ViewModel and create/bind a DataTemplate. New to Forms 1.3, you can now put resources in the Application-level, so you can more easily share those instances.

Here’s the complete code, sans-usings, to implement your own. This can go either in a Shared code or PCL:

public class ContentPresenter : ContentView
{
    public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(ContentPresenter), null, propertyChanged: OnItemTemplateChanged);

    private static void OnItemTemplateChanged(BindableObject bindable, object oldvalue, object newvalue)
    {
        var cp = (ContentPresenter)bindable; 

        var template = cp.ItemTemplate;
        if (template != null)
        {
            var content = (View)template.CreateContent();
            cp.Content = content;
        }
        else
        {
            cp.Content = null;
        }
    }

    public DataTemplate ItemTemplate
    {
        get
        {
            return (DataTemplate)GetValue(ItemTemplateProperty);
        }
        set
        {
            SetValue(ItemTemplateProperty, value);
        }
    }
}

If you want, you can get fancy with Triggers and change the ItemTemplate to vary based on whatever conditions you want.

Beware: Xamarin beta channel is borked!

September 12, 2014 Coding No comments

Here’s the core issue: Xamarin’s QA screwed up with the beta channel on Windows. If you use any portable class libraries in your projects (even if not at all Xamarin related!), VS will fail to load them due to a Xamarin bug. This is pretty poor and should never have made it to beta.

That said, if you want to use Xcode 6, you need to use Xamarin.iOS 8 on your Mac. Problem is that the stable version of Xamarin for VS won’t work with that…needs the matching beta. If you try to use Xcode 6 with the stable Xamarin.iOS, it can’t debug…so bam.

I’m sure this will be cleared up very shortly, but you might want to refrain from either installing Xcode 6 on your Mac or using the Xamarin beta channels for the next several days. Version 3.6.197 on Windows is the bad one….they say it’s fixed already, so the question is how quickly can the push an update out.

Announce: Ninject for Xamarin (and everything else)

August 4, 2014 Coding 2 comments , , ,

I’m happy to announce Ninject support for Xamarin.iOS and Xamarin.Android. Together with the previous release, which included support for Universal Apps, Ninject now supports every major platform in a single Portable.Ninject NuGet package.

Not being enough to simply support each platform, the Portable.Ninject package includes a Portable Class Library (PCL) reference assembly so you can reference Ninject in your PCL’s. Just make sure to also add the NuGet reference to your main application so the “real” bits get used instead of the reference assemblies. This means it’s easy to have NinjectModule‘s in your portable code.

For more documentation, please visit the Dojo or the Wiki.

To get started

  1. Add the Portable.Ninject package to your project.
  2. If your project is a PCL, also add the package to your main app.
  3. Somewhere in your main app, usually your App class (Windows), AppDelegate (iOS), or Application class (Android), create the Kernel and load your types/modules.

Limitations

This package just has the core Ninject functionality. Much of Ninject’s power comes from its extensions, including Convention Based Binding and Factory. These extensions have not yet been forked and updated to work with Portable.Ninject, but they shouldn’t be hard to do. Please drop a note to let me know which extensions you’d like to see brought over.

Contributing

Contributions are very much welcome! Please clone/fork my repo and use the bait-switch branch as your starting point. The solution contains unit test projects for all platforms; to run the xUnit ones for Wpa81 or Win8, you’ll need the latest xUnit runner for Visual Studio extension installed too.

Fluent Assertions 3.1 for Xamarin

July 29, 2014 Coding No comments ,

I’m happy to announce that Dennis Doomen and I have coordinated to sim-ship Xamarin support for Fluent Assertions 3.1 along with the main Fluent Assertions release. This release works well with xUnit for Xamarin or Xamarin’s existing nUnit/nUnitLite.

You can find the main release notes here.

To use Fluent Assertions with your Xamarin Unit Test project, just add a NuGet reference to FluentAssertions.Xamarin.

Happy testing!

Getting Started with xUnit for Xamarin

July 10, 2014 Coding 3 comments , , ,

xUnit.net 2.0 supports both Portable Class Library (PCL) and platform specific projects for iOS and Android.
Unit tests for Xamarin have two main components, which may reside in the same assembly. This post will show you how to get started.

Requirements

  • Xamarin Studio 5.0
  • Visual Studio 2013 Update 2 with the latest Xamarin for Visual Studio

Architecture

Xamarin support consists of two logical components, which may be in the same assembly or may be split:
1. Assemblies containing tests. This may be either a Xamarin project or a PCL. This assembly contains your test classes.
2. App for running tests on a device or simulator. This bootstraps the tests. It’s important that you set any permissions, such as internet access, geo locations, notifications, etc, if your app requires it.

The Goods

For simplicity here, we’ll put both pieces in the same project, but you can also put your tests in a separate library and reference it in your runner app. We’ll use Android as an example, but it’s exactly the same for iOS.

  1. Create a new blank Android project:

  2. Add the NuGet references for xUnit and xunit.runner.xamarin. Make sure the Prerelease option is enabled as xUnit 2.0 is still in beta.


  3. After installing the package, you’ll see a file MainActivity.cs.txt (on Android or AppDelegate.cs.txt for iOS). Copy/paste the contents of that file into your real MainActivity.cs file. Congratulations, your runner app is now ready, you just need to add some tests!

  4. Create a new test class and start creating your tests. For more info on xUnit, check out the Getting Started page.

  5. When you’re ready to run your tests, just debug/run your app as you would any other. You can use a device or simulator.

Current status on the Runners

The runners today are functional, but they’re not pretty. The iOS and Android runners do share quite a bit of code, but the UI is duplicated as it was created before Xamarin.Forms was announced. There’s a ton of room for improvement and I welcome any help in the form of a Pull Request. The code is all on GitHub here.