Thursday, July 25, 2013

Xamarin 4.8 Stable... not sure....

If any MvvmCross get asked today if they want to upgrade to 4.8, then my advice is "wait"


Unfortunately, if you do a fresh install on a Mac, then try the sequence "File->New->Portable Class Library" then that library will not build. The build gives lots of errors about "predefined type XXX is not defined or imported"


I think this will probably be easy to fix - it will probably be down to the PCL reference assemblies - but until some brave leading-edge adventurers have worked this out, then it might be wise to "wait" and not to install the 4.8.0 version


 Hopefully soon this will get resolved - then we can async/await :) :) :)


Wednesday, July 24, 2013

Map Annotation DataBinding

From my answer to http://stackoverflow.com/questions/17816684/using-mvvmcross-how-can-i-bind-a-list-of-annotations-to-a-mapview/17834923#17834923





Subscribing to changing collections is one of the corner-stones of Data-Binding and relies on a little knowledge of the INotifyCollectionChanged interface.

Within the MvvmCross source, there are a few example classes which show how to subscribe to collections and their change notifications - e.g. MvxViewGroupExtensions.cs in Droid and MvxTableViewSource.cs in Touch

The core to the technique is to create an Adapter or Source object which listens for changes either in the whole list or to parts of the list and which takes action accordingly.

The same type of approach applies for maps with multiple - but markers - although we don't yet have any helper classes for this.



Without actually having a Mac or iOS device to hand, here are roughly the steps I'd take to create a wrapper...

Assuming I had a Model object like:

public class House
{
    public double Lat { get; set; }
    public double Lng { get; set; }
    public string Name { get; set; }
}

Inside a ViewModel like:

public class FirstViewModel : MvxViewModel
{
    public ObservableCollection HouseList { get; set; }
}

With this done, then in the View we can create an annotation class for each House - e.g. something like:

public class HouseAnnotation : MKAnnotation
{
    public HouseAnnotation(House house)
    {
        // Todo - the details of actually using the house here.
        // in theory you could also data-bind to the house too (e.g. if it's location were to move...)
    }

    public override CLLocationCoordinate2D Coordinate { get; set; }
}

We could then create a HouseAnnotationManager who's responsibility would be to manage the translation of changes in the HouseList being mapped to changes in the annotations being displayed on the map.

To do this, we would give the manager methods to:
  1. Create a single annotation:

    private MKAnnotation CreateAnnotation(House house)
    {
        return new HouseAnnotation(house);
    }
    
    
  2. Add an annotation to the map (and to a local lookup table)

    private void AddAnnotationFor(House house)
    {
        var annotation = CreateAnnotation(house);
        _annotations[house] = annotation;
        _mapView.AddAnnotation(annotation);
    }
    
    
  3. Remove an annotation from the map (and from a local lookup table)

    private void RemoveAnnotationFor(House house)
    {
        var annotation = _annotations[house];
        _mapView.RemoveAnnotation(annotation);
        _annotations.Remove(house);
    }
    
    
  4. Do the same actions for lists:

    private void AddAnnotations(IList newItems)
    {
        foreach (House house in newItems)
        {
            AddAnnotationFor(house);
        }
    }
    
    private void RemoveAnnotations(IList oldItems)
    {
        foreach (House house in oldItems)
        {
            RemoveAnnotationFor(house);
        }
    }
    
    
  5. Respond to INotifyCollection changes:

    private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                AddAnnotations(e.NewItems);
                break;
            case NotifyCollectionChangedAction.Remove:
                RemoveAnnotations(e.OldItems);
                break;
            case NotifyCollectionChangedAction.Replace:
                RemoveAnnotations(e.OldItems);
                AddAnnotations(e.NewItems);
                break;
            case NotifyCollectionChangedAction.Move:
                // not interested in this
                break;
            case NotifyCollectionChangedAction.Reset:
                ReloadAllAnnotations();
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }
    
    
  6. Respond to whole list changes:

    // MvxSetToNullAfterBinding isn't strictly needed any more 
    // - but it's nice to have for when binding is torn down
    [MvxSetToNullAfterBinding]
    public virtual IEnumerable ItemsSource
    {
        get { return _itemsSource; }
        set { SetItemsSource(value); }
    }
    
    protected virtual void SetItemsSource(IEnumerable value)
    {
        if (_itemsSource == value)
            return;
    
        if (_subscription != null)
        {
            _subscription.Dispose();
            _subscription = null;
        }
        _itemsSource = value;
        if (_itemsSource != null && !(_itemsSource is IList))
            MvxBindingTrace.Trace(MvxTraceLevel.Warning,
                                  "Binding to IEnumerable rather than IList - this can be inefficient, especially for large lists");
    
        ReloadAllAnnotations();
    
        var newObservable = _itemsSource as INotifyCollectionChanged;
        if (newObservable != null)
        {
            _subscription = newObservable.WeakSubscribe(OnItemsSourceCollectionChanged);
        }
    }
    
With this all written, then your ViewModel can have a private _manager field and can create and data-bind it as:

        _manager = new HouseAnnotationManager(myMapView);

        var set = this.CreateBindingSet();
        set.Bind(_manager).To(vm => vm.HouseList);
        set.Apply();


Overall, this might look something like: https://gist.github.com/slodge/6070386

Disclaimer: this code hasn't been compiled let alone run, but the approach is basically correct (I think)



The same basic approach should also work in Android - although in Android you'll also have to fight a battle against the setup - Ant, Google Play v2 and all that jazz.



If you wanted to do further map manipulations - e.g. changing the map center and zoom when a house is added, then this can obviously be done from within overrides of methods such as AddAnnotation within your manager.





The full gist is:

Tuesday, July 23, 2013

MvvmCross 3.0.10 binaries released to nuget, GitHub and skydrive

3.0.10 is a fairly small release - just a few small patches to 3.0.9 from 10 days ago.


I really hope this might be the last release before we switch to Xamarin official PCLs - I might even label those releases 3.1.x


The list of 3.0.10 changes is:
  • minor nuspec file fix - ResourceLoader now availble for WPF
  • a DataContext is now non-virtual everywhere - this may be a breaking change for anyone who was overriding it in their tableviewcells, in an MvxView or in a MvxFrameControl. The recommended solution for the breaking change is to use Binding for all DataContext changes.
  • UIDatePicker now has a "Time" binding - can be used to bind to  a TimeSpan - see ApiExamples project for use
  • In order to support textbox to decimal number binding (see #350), we've changed the binding layer so that:
    1. source (viewModel) bindings do not update the ViewModel if the new value Equals the existing value
    2. for the specific cases of double, float and decimal source values the target bindings do a text-numeric equivalent comparison before setting the UI
  • Fixed "whole object" binding which was broken in 3.0.9 by the Tibet binding changes - the workaround for this in 3.0.9 was to use a period "." for the whole object path (see http://stackoverflow.com/questions/17729282/error-when-making-bind-observablecollectionstring-for-a-mvxlistview/17729996#17729996)
  • Minor changes to design time helpers for Visibility and Color
  • Fixed the MvxPickerViewModel to allow its choice list to be updated dynamically (#354)
  • Groups of Bindings can now be removed from a BindingContext using a ClearKey. To specify the ClearKey for FluentBinding, use the `.WithClearBindingKey(key)` extension (linked to http://stackoverflow.com/questions/17680846/mvvmcross-clearbindings-how-to-use-in-touch and #358)

I've run this build against our unit tests (more still needed), against a significant chunk of the MvvmCross-Tutorials samples, and against some 'new project' tests. All seemed good :) Hopefully this release hasn't broken too much .... as I'm off on holiday real soon :)

Monday, July 22, 2013

Playing with Constraints - FluentConstraints and FluentLayouts for Xamarin.iOS

Update: code now fully shared at https://github.com/slodge/Cirrious.FluentLayout


If you've watched any of the N+1 series - http://mvvmcross.wordpress.com/ - then you'll no doubt have seen me writing a lot of repetitive, error-prone layout code like:


       var textView = new UITextField(new RectangleF(10, 100, 300, 30));
       Add(textView);
       textView.InputView = picker;
       var label = new UILabel(new RectangleF(10, 130, 300, 30));
       Add(label);


All of this repetitive, error-prone layout code was... of course... unnecessary.  The problem was that I am a dinosaur and sometimes it takes me time to learn what I should be doing...


iOS6 is now almost a year old - and part of iOS6 was a new layout system called constraints. The basic idea behind these constraints is that it allows you to specify relationships between the layouts of UIView objects and their attribute values- so that you can, for example, ask one view to set its Top equal to the Bottom of another view. When you do this, then iOS/UIKit will then try to work out the layout for you at runtime.


I've been playing with these today and they are fabulous - especially when coupled with the power of C# - expect to see more of them in my demos soon!


One gist of code that really makes this lovely is Frank's Easy Layout DSL - see http://praeclarum.org/post/45690317491/easy-layout-a-dsl-for-nslayoutconstraint



This expression based library let's you use simple C# statements to define your layout - it's best summarised by code - see his picture which shows how to layout a button and a text box:





For my experiments I decided to see if I could create a Fluent-style API for the same type of effect. I've nothing against the 'Easy Layout DSL' - I just wanted to learn the constraints for myself, plus I wanted to see if using a Fluent approach gave me more composability and reusability.


What I wanted to do was to see if I could define Frank's 'text and button' layout using Fluent code like:


            View.AddConstraints(
                    button.AtTopOf(View).Plus(vPadding),
                    button.AtRightOf(View).Minus(hPadding),
                    button.Width().EqualTo(ButtonWidth),
 
                    text.AtLeftOf(View, hPadding),
                    text.ToLeftOf(button, hPadding),
                    text.WithSameTop(button)
                );


It turned out that it took a bit longer than I had hoped - there were a few gotchas along the way, mainly to do with "TranslateAutoresizingMaskIntoConstraints" - but within a couple of hours I had this working :)


And once I had that working, I then started to play....


What would a form layout look like?

View.AddConstraints(
 
    fNameLabel.AtTopOf(View, vMargin),
    fNameLabel.AtLeftOf(View, hMargin),
    fNameLabel.ToLeftOf(sNameLabel, hMargin),
 
    sNameLabel.WithSameTop(fNameLabel),
    sNameLabel.AtRightOf(View, hMargin),
    sNameLabel.WithSameWidth(fNameLabel),
 
    fNameField.WithSameWidth(fNameLabel),
    fNameField.WithSameLeft(fNameLabel),
    fNameField.Below(fNameLabel, vMargin),
 
    sNameField.WithSameLeft(sNameLabel),
    sNameField.WithSameWidth(sNameLabel),
    sNameField.WithSameTop(fNameField),
 
    numberLabel.WithSameLeft(fNameLabel),
    numberLabel.ToLeftOf(streetLabel, hMargin),
    numberLabel.Below(fNameField, vMargin),
    numberLabel.WithRelativeWidth(streetLabel, 0.3f),
 
    streetLabel.WithSameTop(numberLabel),
    streetLabel.AtRightOf(View, hMargin),
 
    numberField.WithSameLeft(numberLabel),
    numberField.WithSameWidth(numberLabel),
    numberField.Below(numberLabel, vMargin),
 
    streetField.WithSameLeft(streetLabel),
    streetField.WithSameWidth(streetLabel),
    streetField.WithSameTop(numberField),
 
    townLabel.WithSameLeft(fNameLabel),
    townLabel.WithSameRight(streetLabel),
    townLabel.Below(numberField, vMargin),
 
    townField.WithSameLeft(townLabel),
    townField.WithSameWidth(townLabel),
    townField.Below(townLabel, vMargin),
 
    zipLabel.WithSameLeft(fNameLabel),
    zipLabel.WithSameWidth(townLabel),
    zipLabel.Below(townField, vMargin),
 
    zipField.WithSameLeft(townLabel),
    zipField.WithSameWidth(zipLabel),
    zipField.Below(zipLabel, vMargin),
 
    debug.WithSameLeft(townLabel),
    debug.WithSameWidth(zipLabel),
    debug.AtBottomOf(View, vMargin)
 
); 
 
... although I think there are some opportunities to shorten that code and perhaps also to use some code-based hints too!


Could I create a generic vertical scrolling StackPanel/LinearLayout?


 public static IEnumerable<FluentLayout> 
       VerticalStackPanelConstraints(
          this UIView parentView, 
          Margins margins,
          params UIView[] views)
 {
     margins = margins ?? new Margins();
 
     UIView previous = null;
     foreach (var view in views)
     {
        yield return view.Left()
                         .EqualTo()
                         .LeftOf(parentView)
                         .Plus(margins.Left);
        yield return view.Width()
                         .EqualTo()
                         .WidthOf(parentView)
                         .Minus(margins.Right + margins.Left);
        if (previous != null)
           yield return view.Top()
                            .EqualTo()
                            .BottomOf(previous)
                            .Plus(margins.Top);
        else
           yield return view.Top()
                            .EqualTo()
                            .TopOf(parentView)
                            .Plus(margins.Top);
        previous = view;
     }
     if (parentView is UIScrollView)
        yield return previous.Bottom()
                             .EqualTo()
                             .BottomOf(parentView)
                             .Minus(margins.Bottom);
 }


Adaptive!

One key thing to note about these constraint-based UIs is that they are adaptive - e.g. when you rotate the phone then the layout adapts:

 




The code

The code I created is currently sitting in https://github.com/slodge/MvvmCross-Tutorials/tree/master/QuickLayout/Cirrious.FluentLayout - along with a test MvvmCross project (one level up).


It may later move into an MvvmCross plugin - or into core MvvmCross - but for now it's just sitting there in Tutorials. License is Ms-PL as per normal.


A video demo - laying out a tipcalc view





More?

With all this said and done, whether or not you prefer declarative or Imperative UI code is very much a matter of taste... but one question that I'm wondering at the moment is whether I could use the same UI code to create layouts in different environments - whether the same `AtTopOf`, `ToLeftOf` type calls could be used to generate UIKit, Xaml or Axml... but that question will have to wait for another day....

Friday, July 19, 2013

Nuget, Async, PCL links

As some of you know, I'm a dinosaur.


Because of this, there isn't much coverage here of the new nuget, async and PCL toys in the very latest Xamarin Alpha and Beta releases.


If you are hungry for some nuget, async and PCL fixes, then please try:



It's looking awesome - the portable packageable async future has arrived :)



If you think, I've missed a link.... then let me know and I'll add it :)

Wednesday, July 17, 2013

N=36 - A Rio Binding Carnival :)

Today's N+1 follows on from the previous Tibet video - N=35 - which was all about Views and multibinding.


Rio Binding today is all about ViewModels.


Rio is an attempt to experiment with different types of ViewModel. In particular to:

  • use 
    • fields
    • methods 

  • instead of
    • properties
    • commands.


Using the FieldBinding and MethodBinding plugins from Rio, a view model can look like:





instead of an old-skool-INotifyPropertyChanged ViewModel like:





Rio is an attempt to start a conversation.:

  • Which ViewModel style do you prefer? 
  • Why? 
  • What else could be tried?
  • How could anyone do better?


Please note that no-one is saying that Rio field- and method-binding is better than the established property and command binding. All it does for now is to offer some new alternatives. Always think about your code and always choose the tools and techniques which suit you, your team and your app best - the app is king!





The source for today's video is at: https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-36-Rio


A full N+1 index is available on:

Tuesday, July 16, 2013

If you are doing Android Mvvm and you've not looked at a ViewPager...

You *need* to watch:




Then read about it at:

N=35 - MultiBinding with Tibet - N+1 Videos of MvvmCross

Fresh from the heat and Summer-sunshine of London, today's N+1 introduces the new 'Tibet' binding engine.


This binding engine is built on top of the old 'Swiss' engine - so should be fully backwards compatible.


In addition to all the awesome syntax you had in Swiss, you can now take advantage of:
  • Multi-binding
  • Simple combination operators
  • The `Format` combination operator
  • The `If` combination operator
  • Recursive nesting of combinations and of value conversions
  • Function-style invocation of value converters

There's some good documentation on Tibet binding being authored over on https://github.com/slodge/MvvmCross/wiki/Databinding#tibet


This includes examples like:

   Value Format('Hello {1} - today is {0:ddd MMM yyyy}', TheDate, Name)

and

   Text Length(Trim(FirstName + ' ' + LastName))



Tibet has proven quite a hard topic for me to introduce... but I've had a go in this intro video:





The code for the video is at: https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-35-Tibet


For a full N+1 index, see:
http://mvvmcross.wordpress.com

Friday, July 12, 2013

Badges.... Who have I missed?

Badges.... Who have I missed?


I love seeing MvvmCross improve - and the badges are a small attempt to say 'thank you' and to recognise all of the fab community contributions.


Here are all the winners so far this year - I try to include this slide in all my talks - I really can't say 'thank you' enough!




However... I'm working hard at present - working with some amazing customers across 4 continents and across far too many timezones! So I may have missed some contributions that I probably shouldn't have...


Who have I missed? 


Let me know! Nominate someone for a badge... and they *might* get one ;)

Splat awesomeness

Since April 2012 MvvmCross has been pushing PCLs forwards as a key part of the future of mobile development.

As part of this, we've produced our own plugins for things like image loading and our own abstractions for things like Colo(u)r.

One new project that's recently started is the splat project - see https://github.com/xpaulbettsx/splat

This project aims to provide more cross-platform portable low-level abstractions - like Color, Point, Rect, etc - and to provide some higher-level utilities too - like Image loading from resources.

This type of thing is obviously really useful to anyone creating PCL-based apps - so it should be really useful to anyone using, extending or building MvvmCross...

Paul Betts - this is awesome - welcome to the dystopian PCL future - a badge of portable awesomeness - thanks!







Also... while you are checking out Splat, be sure to also check out ReactiveUI too - STAR THEM BOTH TODAY!

Persistently awesome - Ninja Sudbury

As badges of awesomeness go, this is a first... this one's awarded for **persistent awesomeness**

As some of you may have already seen, the MvvmCross Ninja plugin for Visual Studio just keeps getting better.

This is all down to one person - @asudbury - he keeps churning out more and more features, fixing bugs and tracking the main project releases to make sure the Ninja is up to date.

This was particularly helpful to me as I prepared for my hour session at NDC, and for my 30 minute session at BCS Scotland. When you've only got 30 minutes for a talk and demo, it's brilliant to have a tool that generates a core project, a test project and all the UIs for Windows WPF, WIndows Store, Windows Phone, Xamarin.Android and Xamarin.Mac - all inside 45 seconds!

Adrian - sometimes known as Scorchio - Awesome Badge #3 - thanks!




"put all the pieces together" - awesome from @PeterSvitz

One of the key objectives for MvvmCross v3 was to make 'Getting Started' easier.

We've made quite a lot of progress on this - especially through Nuget, through some initial documents and through community contributions like the Ninja coder for MvvmCross

However, there's still some setup barriers - especially while we're still ironing out the official integration with PCLs for Xamarin (although there is really great progress on that currently!)

Because of this, community posts which help people with setup knowledge are really very important - and one such setup guide is @PeterSvitz's guide at http://psvitz.com/xamarin-vs2012-pcl-mvvm-cross-v3-awesome1one1/

Completely awesome work - thanks @PeterSvitz - awesome :)


UISearchBar binding - thanks mverm!

Lots of MvvmCross UI bindings 'just work' - when your control has a property called XYZ and an EventHandler event called XYZChanged then MvvmCross just automatically binds to the property-and-event pair.


However, for less conventional controls - e.g. for controls which usse EventHandler or for controls with custom get/set method APIs - then MvvmCross needs custom bindings.




One such control is the iOS UISearchBar - and one user, mverm, noticed this, created a binding for their app, then contributed that binding back to the community.


This is awesome - thanks - very, very happy to award a badge for this contribution - thanks!



@robfe - awesome bug hunter

It's not often that a single person gets two badges of awesomeness inside a few days...

But recently, @robfe logged and fixed a huge and very important fix in the MvvmCross Sqlite plugin - spotting that in some circumstances our interface implementation caused Linq2Sqlite to revert to Linq2Objects

This is a really important fix... and it's awesome and so @robfe earns a second badge, plus is promoted into the MvvmCross hall of bughunters!



Full credit for original bug hunter image to http://www.gregbroadmore.com/imgpg.php?page=126 - and thanks for letting me post it :)





Thursday, July 11, 2013

Dialog Awesomenessssssssssssss!

Within the MvvmCross repo, we've got a specialist fork of MonoTouch.Dialog, MonoDroid.Dialog and we've got our own default UI code - AutoViews.

Recently this code has been receiving lots of love, attention, skill and dedication from 2 individuals: @hhubschle and csteeg

Among the fixes and improvements, we've had:

  • increments in Time and Date pickers on both Touch and Droid
  • increments in edit text controls
  • test apps in DialogExamples and AutoViewExamples
  • vastly improved AutoView creation
  • lots of action in other controls too - e.g. in Achievements/Badges

All of this is brilliantly awesome - it's fab to see this Dialog code getting new functionality and fixes - completely awesome and totally deserving of two badges of awesomeness - thanks for the contributions guys:








Awesome Talbott-Gaga in Boston

In the middle of June, I got this tweet:


I followed up and discovered this talk that @talbott had given to the Boston developers.




Original Link


It's completely awesome - 100% awesome - so very happy to award @talbott a Gaga-badge of awesomeness.



Les vidéos super-impressionnant - @odenaxos

Last year, MvvmCross got some awesome input from Olivier in France - he published some long, detailed and awesome posts on how to use Mvvm cross-platform and how to reuse an existing Silverlight app in the new platforms and how to use MvvmCross vNext IoC.

The excellent news is... in the last few weeks, @odenaxos has returned - he's back with some new articles and screencasts about v3.

Check these out in:


As someone who's made a few videos recently, I can really recognise the time and attention that @odenaxos has put into these - he's taken real care to provide some high-quality, well-edited, nicely-crafted tutorials - they are awesome!

Olivier - merci - voila un badge d'awesomeness!


Xamarin 2.0 activation sucks

I love the Xamarin 2.0 improvements that arrived this year.

I now sit there on my PC and deploy to 5 operating systems and to websites from a single solution.

It's fabulous!

However...

I've had a lot of problems with Xamarin activation during the last 6 months. To put it bluntly, it's flakey and it's cost me weeks of wasted time.

It seems to randomly decide that I need to reactivate my software - at which point it refuses to work until it can connect to some bit of Xamarin's servers... and even then it often fails...

For example, this morning on the train I was trying to do some work...

Only, up came this window...



But I'm on the train... and I can't get on the Internet...

So I have to hit cancel...



... so Xamarin simply says "No, you can't work now" - it won't even let me open the project.




... which gives me the rest of the train journey to draft this blog post...

Wednesday, July 10, 2013

Jason@Aviva and Jake@Aviva - Driven to Awesomeness

In early 2012, Jason, a developer at Aviva asked the infamous 'Hindsight' question about MvvmCross on StackOverflow - http://stackoverflow.com/questions/10224376/mvvmcross-experiences-hindsight-limitations

Armed with this hindsight, he and his team went on to ship the awesome 'Aviva Drive' app - a driving app which attempts to work out, share and benefit from how good a driver you are:




In this last month, this app has been featured in the TechEd Europe keynote:


Aviva Drive - Case Study from Dare on Vimeo.

...and beyond that, two of the Aviva Drive team - Jason and Jake - have also presented a workshop on MvvmCross coding at the new @ModDevCon conference in Norfolk.

This is really, really, really awesome - and earns Jason and Jake an excellent canary yellow badge of awesomeness each:


Awesome clean ViewModels via Fody

Sometimes ViewModels can be a bit verbose... e.g. sometimes achieving a simple FirstName and LastName combination can require:



Because of this, sometimes some of us find ourselves thinking wouldn't it be nice if our ViewModels were thinner - e.g. a bit more like:



Well, @TwinGuille didn't just think this - he went off and coded it!

Using the tools from @SimonCropp's excellent Fody - https://github.com/Fody - @TwinGuille posted an awesome blog post on how to achieve thinner, slimmer, easier-to-code, easier-to-understand ViewModels.

This is 100% awesome - check it out at http://twincoders.com/blog/codigo-limpio-con-fody/ - well deserving of a badge of awesomeness.