Some Caliburn.Micro tutorial/info links.

Here are a few links that may help people getting started with Caliburn.Micro:

This is an excellent and clear introduction to using the latest version of Caliburn.Micro. First of 5 articles (at the time of writing this).
http://claytonone.wordpress.com/2014/06/14/caliburn-micro-part-1-getting-started/

Detailed tutorial (based on earlier version of CM). Includes articles on Multiple Views and Unit Testing.

http://iserialized.com/getting-started-with-caliburn/

Useful short article on Async/Await with Caliburn.Micro. Close to my heart as I used Async/Await extensively in a recent instrument control and communication Application.

http://caraulean.com/blog/2013/07/15/using-caliburn-micro-with-async-await/

About using the EventAggregator to send messages (Windows phone app).

http://joshearl.wordpress.com/2011/03/31/introduction-to-messaging-with-caliburn-micros-eventaggregator/

A Question/Answer on using SimpleContainer as IoC.

http://www.answerques.com/szBJgSWXgxWU/how-to-use-caliburnmicro-simplecontainer-in-data-layer

Introduction to Caliburn.Micro on Windows Phone 8 – scroll down to 14 November 2013 !

http://dutton.me.uk

Templates for Visual Studio 2012/2013 – contains a couple of Caliburn.Micro ones. I haven’t tried or tested any.

http://sidewaffle.com

Hope they’ll be useful for those learning Caliburn.Micro.

Using Caliburn.Micro (version 2) for WPF development.

Part 1: A simple application illustrating some basic Caliburn.Micro concepts.

This item is based on the Caliburn.Micro documentation and Silverlight example here: http://caliburnmicro.codeplex.com/wikipage?title=Basic%20Configuration%2c%20Actions%20and%20Conventions
Apart from the additions of the DisplayName and TextBox colour items I make no claim to originality of the text – it is highly based on the original Caliburn.Micro “Soup to Nuts” documentation here: https://caliburnmicro.codeplex.com/documentation. I have merely adapted the code and text to illustrate the usage of Caliburn.Micro with WPF rather than Silverlight.

The Caliburn.Micro2.Hello Application

First create a WPF Application project in C# named Caliburn.Micro2.Hello

To add the latest (v2) Caliburn.Micro via NuGet:

Tools | NuGet Package Manager

If under the Package Manager Console install using the PM> Install-Package Caliburn.Micro command otherwise in the UI Manager search for Caliburn.Micro and install the Caliburn.Micro package only.

This will, actually, install both Caliburn.Micro and Caliburn.Micro.Core as well as a number of other required dependencies under the project References.

We are now ready to modify the structure and code for MVVM and Caliburn.Micro.

Add the following three folders to the project:

Models

ViewModels

Views

These serve as locations to keep the various items neatly separate! This example is simple enough not to need them (and the original tutorial does not use them). However, it is a good practise to start including these from the beginning.

Note: From now on I will use CM as an abbreviation for Caliburn.Micro.

Because CM uses its own Views you should delete the MainWindow.xaml file and remove the StartupUri item from App.xaml (StartupUri=”MainWindow.xaml”)

Change App.xaml.cs to:

using System.Windows;

namespace Caliburn.Micro2.Hello
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
}

Because CM prefers a View-Model-First approach, let’s start there. Create your first ViewModel in the ViewModels folder (Add C# class) and call it MainViewModel. Use the following code for the implementation:

using System.Windows;
using Caliburn.Micro;
namespace Caliburn.Micro2.Hello.ViewModels
{
    class MainViewModel : PropertyChangedBase
    {
        string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                NotifyOfPropertyChange(() => Name);
                NotifyOfPropertyChange(() => CanSayHello);
            }
        }

        public bool CanSayHello
        {
            get { return !string.IsNullOrWhiteSpace(Name); }
        }

        public void SayHello()
        {
            MessageBox.Show(string.Format("Hello {0}", Name)); //Don't do this in a real software project
        }
    }
}

Notice that the MainViewModel inherits from PropertyChangedBase. This is a CM base class that implements the infrastructure for property change notification and automatically performs UI thread marshalling.

There is a string property, Name, which uses CMs NotifyOfPropertyChange in set and a bool CanSayHello (read only) property which has a CM related method SayHello. SayHello just displays a MessageBox showing Name – this is for the example only – you wouldn’t want to “pollute” the view model with a UI “view” action in this way.

Note: The SayHallo method will become a button press action from a button named SayHello in the View. The boolean CanSayHello follows the CM convention and is used to enable/disable the button named “SayHello” in the View. These are based on standard naming conventions provided by CM.

We now need to create the bootstrapper that will configure the framework and tell it what to do. Create a new class named AppBootstrapper in the project “root” area. You can use this short item of code:

using System.Windows;
using Caliburn.Micro;
using Caliburn.Micro2.Hello.ViewModels; 

namespace Caliburn.Micro2.Hello
{
    class AppBootstrapper : BootstrapperBase
    {
        public AppBootstrapper()
        {
            Initialize();
        }
         protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor<MainViewModel>();
        }
    }
}

BootstrapperBase is a class provided by CM.

The Bootstrapper allows you to specify the type of “root view model” via the generic method (DisplayRootViewFor). The “root view model” is a ViewModel that Caliburn.Micro will instantiate and use to show your application.

Next, we need to place the AppBootstrapper somewhere where it will be run at startup. To do that, change your App.xaml to match this:

<Application x:Class="Caliburn.Micro2.Hello.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Caliburn.Micro2.Hello">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:AppBootstrapper x:Key="bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
     </Application.Resources>
</Application>

Note: Make sure you have removed the StartupUri (StartupUri=”MainWindow.xaml”) from the initial <Application ….> statement.

xmlns:local=”clr-namespace:Caliburn.Micro2.Hello” provides the local namespace

With our CM bootstrapper in the Application.Resources CM will do the rest of the work.

Run the application. You should see something like this:

CM2-Pt1-Image1

We have defined the ViewModel but not yet created the View to go with it.

To do this, create a new UserControl (WPF) in the Views folder with the name: MainView.xaml

<UserControl x:Class="Caliburn.Micro2.Hello.Views.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300"  d:DesignWidth="300">
    <StackPanel>
        <TextBox x:Name="Name"></TextBox>
        <Button x:Name="SayHello" Content="Click Me"></Button>
    </StackPanel>
</UserControl>

The default control has been made a StackPanel – (you can use whichever WPF container you feel comfortable with).

Note that the x:Name items for the two controls match the names of the Property (Name) and Method (SayHello) in the MainViewModel code. It is this that CM uses to implement a convention based binding to certain actions.

Similarly, CM will look for a View with the same name as the ViewModel but without the Model part.

So for MainViewModel, CM looks for and uses a view named MainView.

Run the application and you should see something similar to:
CM2-Pt1-Image2
Type a name into the top text box and the button becomes enabled…
CM2-Pt1-Image3
Clicking the button throws up the message box:
CM2-Pt1-Image4
And we know that the system is working as we intended.

Adding a window title.

It would be quite good to give the App window a title. There’s a quick way to do this.

First, let’s make enough space to display it. In MainView.xaml set the MinWidth to 300.

d:DesignHeight="300" d:DesignWidth="300" MinWidth="300">

Then, in MainViewModel.cs add the IHaveDisplayName interface to the class declaration:

class MainViewModel : PropertyChangedBase, IHaveDisplayName

Implement the one and only property from that interface:

public string DisplayName { get; set; }

And create a simple no-parameter constructor which sets the DisplayName:

public MainViewModel()
{
     DisplayName = "My Hello App";
}

The complete class listing should now look like:

using System.Windows;
using Caliburn.Micro; 

namespace Caliburn.Micro2.Hello.ViewModels
{
    class MainViewModel : PropertyChangedBase, IHaveDisplayName
    {
        string name;
        public MainViewModel()
        {
            DisplayName = "My Hello App";
        }

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                NotifyOfPropertyChange(() => Name);
                NotifyOfPropertyChange(() => CanSayHello);
            }
        }
         public bool CanSayHello
        {
            get { return !string.IsNullOrWhiteSpace(Name); }
        }
         public void SayHello()
        {
            MessageBox.Show(string.Format("Hello {0}!", Name));
        }
         public string DisplayName { get; set; }
    }
}

Run the App and you should see:
CM2-Pt1-Image5
So you now have your App with a title.

Note: The IHaveDisplayName interface is also implemented in CMs IScreen and its Screen class implements IScreen. These are described later and on CM site here: https://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition

It’s a Bind

Let’s try another bit of binding between the View and ViewModel. This time it’ll be a specific item, that isn’t being automatically bound by CM.

Let us add the ability to set the colour of the TextBox from the ViewModel.

First we need to add the backing property and supporting code into MainViewModel:

private Brush _textBackgroundBrush; public Brush TextBackgroundBrush
{
    get { return _textBackgroundBrush; }
    set
    {
        _textBackgroundBrush = value;
        NotifyOfPropertyChange(() => TextBackgroundBrush);
    }
}

This creates a Brush property for the TextBox Background.

Note: This code structure is an excellent candidate for a ReSharper Live Template!

Now add calls in MainViewModel.cs to set the colour in the constructor:

public MainViewModel()
{
    DisplayName = "My Hello App";
    TextBackgroundBrush = new SolidColorBrush(Colors.BlanchedAlmond)
}

and the button click:

public void SayHello()
{
    TextBackgroundBrush = new SolidColorBrush(Colors.Chartreuse);
    MessageBox.Show(string.Format("Hello {0}!", Name));
}

Now we just need the binding in MainView.xaml:

<StackPanel>
    <TextBox x:Name="Name" 
             Background="{Binding TextBackgroundBrush, FallbackValue=LightBlue}">
    </TextBox>
    <Button x:Name="SayHello" Content="Click Me"></Button>
</StackPanel>

The FallbackValue displays in the absence of the Binding, as Binding is only made at Runtime the design colour of the TextBox will be LightBlue.

Run the application and see the colourful effect!

The complete solution is available as a zip download here (developed in Visual Studio 2013)

Catastrophic Failure in Visual Studio 2103 ( SetSite failed for package [DesignerPackage] )

I’ve been away for a couple of days, switched on my development computer, answered a few emails and then started Visual Studio 2013 to do some urgent work for a client.

I was faced by a barrage of message boxes stating that various tools and libraries could not be loaded and mentioning something about a recent update (recent update – as far as I was aware I hadn’t made any recent updates).

The project I was working on appeared to load (Unit Test runner was displayed) but nothing in any of the other panels or windows, and VisualHG seemed to recognise the project. Close and re-open a couple of times and exactly the same messages.

Tried to run the Test Runner and got the message:

ReSharper Failed to build required projects

The build could not be started. Catastropic failure (Exception from HRESULT: 0X8000FFFF (E_UNEXPECTED))

So I decide to re-boot to see if that clears things. It’s then that I see the Update icon on the Shutdown button. So, for some reason Windows has partially updated itself without telling me and screwed up VS2013! Nice one MicroSoft!

Checked ActivityLog.xml and it had loads of RED Errors – mostly MicroSoft items.

After the re-boot VS2013 was still totalled, and a quick bit of browsing found this:

http://www.jasonlinham.co.uk/2012/01/setsite-failed-for-package-visual.html

The ResetSettings parameter process did not work.

As I write this I’m running Repair on VS2013 (watching paint dry)…. Cancelled it because it was taking so long at the Preparation stage.

Later: It took about 30 minutes to complete the cancellation process but reported 93 of 96 items updated at the end and requested a reboot of the PC. After doing this VS2013 opened as though it had been just updated BUT it opened and displayed the projects and seemed to be working ok.

Luckily I had not attempted to run VS2012 before the reboot. When I did – it worked and loaded the project ok.

Lessons:

1) Be aware of when Windows has started one of it’s updates – if it’s halfway through it’ll screw up your Visual Studio if you try to run it.

2) If one version of Visual Studio is messed up – DO NOT TRY TO test another version of Visual Studio before the update has been completed !

 

Tools of the Trade: .NET DEMON

I’ve been using RedGate’s .NET DEMON for a couple of years and find it to be one of those simple but very useful utilities.

What it does: Builds your project – as you write code. So you get instant feedback on any build errors – if there are none then your project is always built and ready to run.

An indicator in the lower right status bar shows the build state: Green (All project up to date) = successful build; Red = Error (View Error: Shift+Alt+Ins) = failed build. So you can find and fix errors as you type. It is fast – it’ll show an error as you’re typing a statement before you get to the statement terminator ;

It works in VS2010 and higher – but, unfortunately NOT in VS2008 (unfortunately, because I still do a lot of project work in VS2008 and it would really help in that).

As a (mostly) solo developer I’ve found it an excellent tool – I almost forget it’s there – running away in the background – apart from keeping an eye on the little indicator.

A number of options allow you to control when and how it runs, and whether it replaces the Visual Studio build system with it’s own optimized build system.

It’s relatively inexpensive at under £20 for a single developer or small company and, as you’d expect, there’s a time limited trial version.

Well worth checking out:

http://www.red-gate.com/products/dotnet-development/dotnet-demon/

A couple of Resharper Live Templates for Caliburn.Micro items.

These are a couple of Live Templates for Resharper that help with some of the property declarations to work with Caliburn.Micro (the WPF framework originally from Rob Eisenberg).

I just use the naming convention CM followed by the purpose of the template. Both are available as a zip file via the link at the end of this article.

CMButton:

        private bool _can$BUTTONNAME$;
        public bool Can$BUTTONNAME$
        {
            get { return _can$BUTTONNAME$; }
            set
            {
                if (_can$BUTTONNAME$ == value) return;
                _can$BUTTONNAME$ = value;
                NotifyOfPropertyChange(() => Can$BUTTONNAME$);
            }
        }
        public void $BUTTONNAME$()
        {
           throw new NotImplementedException();
 
        }

This creates both the Button action method and the Can<method name> flag which is automatically used by Caliburn.Micro to enable/disable the button.

Only one item to complete ($BUTTONNAME$) when you use the template. Usually typing c m b is enough to get the template selected.

If you enter the button name as Edit the resulting code is:

        private bool _canEdit;
 
        public bool CanEdit
        {
            get { return _canEdit; }
            set
            {
                if (_canEdit == value) return;
                _canEdit = value;
                NotifyOfPropertyChange(() => CanEdit);
            }
        }
 
        public void Edit()
        {
            throw new NotImplementedException();
 
        }

Saves a whole load of typing! In the XAML you use x:Name = “Edit” in the <Button /> declaration and Caliburn.Micro does the rest.

 

CMProperty

        private $TYPE$ _$BACKINGFIELD$;
 
        public $TYPE$ $PROPERTYNAME$
        {
            get { return _$BACKINGFIELD$; }
            set
            {
                _$BACKINGFIELD$ = value;
                NotifyOfPropertyChange(()=>$PROPERTYNAME$ );
            }
        }

Slightly more complex than CMButton. This has three values: $TYPE$, $BACKINGFIELD$ and $PROPERTYNAME$. However, only $TYPE$ and $BACKINGFIELD$ need to be input – $PROPERTYNAME$ is generated from $BACKINGFIELD$.

$TYPE$ is the first item asked for – a drop down list of available Types will appear.

As $BACKINGFIELD$ is private start the name in lower case. The $PROPERTYNAME$ is produced with an Upper case first letter. So if you type firstName the property name will be FirstName.

       private String _firstName;
 
       public String FirstName
       {
           get { return _firstName; }
           set
           {
               _firstName = value;
               NotifyOfPropertyChange(() => FirstName);
           }
       }

And you have your property ready to link to a TextBox (x:Name item again) with Caliburn.Micro.

NotifyOfPropertyChange is a Caliburn.Micro method.

Download the zipped templates.

Save and extract from the zip file. Then import into Resharper Live Templates:

Resharper | Templates Explorer | Live Templates | select C# Scope | Import

I hope that these are useful for some Caliburn.Micro developers.

Binding Property Objects to WPF with Caliburn.Micro

Caliburn.Micro provides some powerful classes to help when working in WPF and I found it a very useful and rapid way to develop a WPF application for a client.

However, I found myself reproducing the same binding properties over and over (for example Foreground and Background colours for Labels, Buttons, TextBoxes, etc.). I thought that there must be a better way of handling the common properties for all these objects – rather than multiple Properties essentially doing the same thing. It seemed unlikely that there wasn’t a way of creating a class that could contain all the properties and be used to bind to the XAML objects.

The solution was suggested in this article by Colin Eberhardt.

Based on this I created the following class in the Models section of the project:

public class CommonControlProperties : PropertyChangedBase
{
 
    public CommonControlProperties()
        : this(new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.White))
    {
    }
 
    public CommonControlProperties(SolidColorBrush foreground, SolidColorBrush background)
    {
        Foreground = foreground;
        Background = background;
    }
 
    private SolidColorBrush _background;
    public SolidColorBrush Background
    {
        get { return _background; }
        set
        {
            _background = value;
            NotifyOfPropertyChange(() => Background);
        }
    }
 
    private SolidColorBrush _foreground;
 
    public SolidColorBrush Foreground
    {
        get { return _foreground; }
        set
        {
            _foreground = value;
            NotifyOfPropertyChange(() => Foreground);
        }
    }
      
}

This inherits Caliburn.Micro‘s PropertyChangedBase which provides the NotifyOfPropertyChange method. It implements only 2 properties for this example: Foreground and Background colours. Two constructors are provided – the basic just sets foreground to black and background to white by default, the second uses two SolidColorBrush items to set the foreground and background colours.

In the ViewModel I then declared an auto implemented Property of type CommonControlProperties:

public CommonControlProperties TestTextBox { get; set; }

This can be instantiated in the ViewModel constructor (or elsewhere):

TestTextBox = new CommonControlProperties();
OR
TestTextBox = new CommonControlProperties
{
    Background = new SolidColorBrush(Colors.Bisque),
    Foreground = new SolidColorBrush(Colors.Red)
};

Finally, the XAML code for the TextBox uses bindings to the ViewModel property and its relevant contained properties.

<TextBox x:Name="TestTextBox1" Background="{Binding TestTextBox.Background}" Foreground="{Binding TestTextBox.Foreground}" HorizontalContentAlignment="Left" Height="27" Margin="43,20,0,0" Grid.Row="3" TextWrapping="Wrap" Text="TextBox1" VerticalAlignment="Top" Width="132" FontSize="14" FontWeight="Bold"/>

This works as expected and allows a neat container for common properties that need to be bound to the XAML objects.

Obviously, this small class needs to be extended to contain all the properties that are useful for controlling the appearance of the visual Control.

SNIPPET: Prevent unwanted window close in Caliburn.Micro

I needed to avoid an unwanted Window close (using the [X] button in top right of Window).

The window is a UserControl inheriting the Caliburn.Micro Screen class (which is needed to provide the functionality).

public override void CanClose(Action<bool> callback)
{ // Prevents closing of window using the [X] button
     callback(_userExit); 
}

Simply override the Screen CanClose method.

_userExit is a private bool that is set in the code. Initialised to false and only set true if the user cicks the one button that is intended to close the window.

Method found on StackOverflow: http://stackoverflow.com/questions/8790526/caliburn-micro-cancel-window-close-from-viewmodel

Strange case of the displaced Combo Box dropdown

I was adding a User Login window for a WPF application in a project that uses Caliburn.Micro. This Window was opened during the Caliburn.Micro OnViewLoaded event and included a ComboBox for user name selection.

Everything worked as expected (though the User Login window appeared before the main view was displayed). However, when the ComboBox was clicked to display the dropdown list of user names the list appeared in the upper left of the screen.

A search showed that this was a known problem and much discussed with some solutions and suggestions. None that I found were specific to working with Caliburn.Micro but this reply on StackOverflow by Ken Salter was enough to provide a succint solution to the problem: http://stackoverflow.com/questions/1998024/wpf-combobox-dropdown-part-appears-in-the-wrong-place

I adapted the code to work in the OnViewLoaded event and this fixed the problem. The ComboBox worked as expected, plus the User Login window appeared after the Main View was displayed.

The code:

              private Dispatcher _dispatcher = Dispatcher.CurrentDispatcher;
        private delegate void DelegateOpenWindow();
        private DelegateOpenWindow _delegateOpenUsersWindow;
 
        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
            _delegateOpenUsersWindow = (ShowUserSelectWindow);
            _dispatcher.BeginInvoke(_delegateOpenUsersWindow);
        }
 
        private void ShowUserSelectWindow()
        {
            dynamic usersWindow = new ExpandoObject();
            usersWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            usersWindow.WindowStyle = WindowStyle.SingleBorderWindow;
            WindowManager.ShowDialog(new UsersViewModel(Events, WindowManager), null, usersWindow);
        }

Dispatcher is provided by the System.Windows.Threading library:

using System.Windows.Threading;

ShowUserSelectWindow is the method I have used to show the User LogIn window (named UsersViewModel). The Delegate and Dispatcher items are directly adapated from Ken Salters example.

Interestingly, one of the discussions included a comment from a Microsoft person where they said this bug would be fixed in .NET 4.5. My project is targetted at .NET 4.5, in VS2013 – Caliburn.Micro is version 1.5.2.0.

No doubt the code could be simplified further and perhaps Async / Await could be used – though I haven’t experimented with that yet.

Some further links on this subject:

http://stackoverflow.com/questions/4677701/c-sharp-strange-wpf-combobox-behavior

http://social.msdn.microsoft.com/forums/wpapps/en-us/545461b5-cf62-48e2-bcfb-2e872ecea639/wpf-tooltips-and-comboboxes-are-in-top-left-corner (the last post is the one that claims it is fixed in .NET 4.5).

https://www.devexpress.com/Support/Center/Question/Details/B202426

 

 

 


 

Installing xUnitContrib Test Runner in VS2008

I use xUnit.net as my main test framework for a range of C# projects, including one in VS2008. This project is for a Windows Mobile 6.5 application and so can’t be moved on to Visual Studio 2010 / 2012 / 2013.

With the new Extension Manager in ReSharper (NuGet) it is easy to install the latest xunitcontrib update (called xUnit.net Test Support in the NuGet listing) into Visual Studio 2010 / 2012 and 2013. However, it is slightly more problematic to install into VS2008. Matt Ellis (Author of xunitcontrib) does supply a batch file to install but this sometimes lags behind the main release via NuGet.

On both the R# 8.0 and 8.1 releases I found that the following worked on my system (Win 7, 64 bit):

  1. Update ReSharper for all versions of Visual Studio.
  2. Update xUnit.net Test Support via the ReSharper Extension Manager in VS2012 (my other main dev environment).
  3. Find the location of the newest xunitcontrib.runner libraries – in my setup they are here (for R# 8.1): C:\Users\<username>\AppData\Local\JetBrains\ReSharper\vAny\packages\xunitcontrib.1.3.0\ReSharper\v8.1\plugins\xunitcontrib.runner.resharper.runner.8.1.dll
  4. I then copy the entire plugins folder to: C:\Program Files (x86)\JetBrains\ReSharper\v8.1\Bin\  .  Both times I have used this method the plugins folder didn’t exist so it was just a clean copy. If it does exist then copy the contents of the original plugins folder (step 3) into the existing one.
  5. Start VS2008 and open your test project – the tests should be marked and ready to work with as expected.

So far, I haven’t encountered any problems using this method and it follows the guidelines given by Matt for installing earlier versions of xunitcontrib.

For more information on the xUnit test runner: xunit.net contrib web site.

Zapped to infinity!

In my last post I’d described my initial set up of Zapier to “synchronise” my Trello and BitBucket systems.

I defined 4 Zaps that seemed to provide the functionality I needed to test Zapier at this point:

  1. When I Open an Issue in BitBucket then Zapier will Create a Card under my Backlog list in my Trello Board.
  2. When I Create a Card in the Backlog list in my Trello board, Zapier will Open an Issue in BitBucket.
  3. When I Create a new Repository in BitBucket the Zapier will Create a New Board in Trello.
  4. When I Push to BitBucket then my Changesets are logged as cards into a BitBucket Log list in my Trello Board.

(Note: All list names in Trello are the ones I use – yours are likely to be different!).

All tested as expected. HOWEVER, the eagle eyed amongst may have spotted the problem – I did leave it as it was initially set up to see if Zapier was intelligent enough to work around the problem (It wasn’t but can be told how to!).

The problem: Zaps 1 and 2 form an infinite loop. This is exactly what happened:  I created new Backlog card in Trello, a few minutes later Zapier Opened the Issue in BitBucket, a few minutes later Zapier Created a new Card from the new Issue and a few minutes later Opened a new Issue in BitBucket….. I let it run for 7 iterations then switched the Zap off.

I contacted Zapier about this and they answered within their stated time scale (a couple of hours, more on their support below). However, by that time I’d worked out the method to avoid the loop! Zapier comes with a rich set of Filters for each service it connects and using these avoids infinite loops or Zap duplication. This is where having a separate Zapier BitBucket account is very useful (though not essential).

The “BitBucket Open Issue to Trello Create Card” filter:

In Section (4) of the Zap edit (Filter BitBucket Triggers) I used the Custom Filters to create a single filter that would avoid any issues opened by my “Zapier” BitBucket account.

The left hand drop down provides a list of BitBucket fields that can be used – I selected reported_by_first_name, then set the middle filter action to (Text) Does not contain and entered the value Zapier in the data field (right most).

Filter used for BitBucket to Trello Zap

Filter used for BitBucket to Trello Zap

This passed the test and now works only when a BitBucket Issue is opened by someone other than “Zapier”!

The “Trello Create Card to BitBucket Open Issue” filter:

This needs a slightly different approach to the previous filter because there is no Zapier Trello user to identify the source of the Card. However, it is easy to add an identifier to the data that is passed via Zapier. This must be done in the “Open BitBucket Issue to Trello Card” Zap – the same one as used to set the filter above.

So I select that Zap for Edit and move down to section 5: Match up BitBucket Issue to Trello Card. Below the Board and List selection boxes are the Name and Description fields.

Zap-BBtoTrelloData

In the Description field I have used the Issue Content (a selectable BitBucket data field) and have also added a literal (Via Zapier) text indicator. This serves to:

  1. show that the card came from BitBucket via Zapier.
  2. act as a filter item to prevent the card getting Zapped back to BitBucket.

This tested ok and teh Zap switched on. This completes the changes needed to the BitBucket Issue to Trello Card Zap.

The next stage is to add the filter to the Trello Card to Bitbucket Open Issue Zap. Edit the Zap and move to section 4: Filter Trello Triggers.

The left hand drop down provides a list of Trello fields that can be used – I selected desc, then set the middle filter action to (Text) Does not contain and entered the value Zapier in the data field (right most).

Zap-TrellotoBBFilter

And that’s it! Test again and switch on the Zap. And it works like a dream! No more infinite loop.

And, as these things tend to happen, after I’d set it up and got it all working I got a detailed reply from Zapier support with the following:

If you want those zaps to work the way you intended but without the duplicates, we put together a guide that lets you use filters and a slight adjustment to how you create those cards/issues to avoid that loop: https://zapier.com/help/avoiding-zap-loops/

The Push to Bitbucket creates new Trello card Zap.

I think this is really good. I push changes to my BitBucket repo and some minutes later a new card appears in my Trello Board BitBucket Log list with the Revision number and Date and Time. There are more details within the card – but this allows a really good overview of the project progress within Trello (a single point of reference).

TrelloPushLogCard

I suspect I am only just at the very beginning of finding all the features and uses of Zapier. But, so far, it is proving its value.