Thursday, April 26, 2012

Getting Location information in MvvmCross

I've added a lesson in the tutorial that shows the IMvxGeoLocationWatcher location fetching interface being used.
      private void DoStartStop()
      {
          if (!IsStarted)
          {
              _watcher.Start(new MvxGeoLocationOptions() { EnableHighAccuracy = true }, OnNewLocation, OnError);
          }
          else
          {
              _watcher.Stop();
          }
          IsStarted = !IsStarted;
      }
      private void OnError(MvxLocationError error)
      {
          // TODO - shuold handle the error better than this really!
          LastError = error.Code.ToString();
      }
      private void OnNewLocation(MvxGeoLocation location)
      {
          if (location != null && location.Coordinates != null)
          {
              Lat = location.Coordinates.Latitude;
              Lng = location.Coordinates.Longitude;
          }
      }  
This seems to work OK on:
I haven't yet written the code for WinRT...

Saturday, April 21, 2012

Experiments with Portable Class LIbraries - mvvmcross

I've tried to refactor mvx into portable class libraries today.

Initial results have been quite promising - so I think it will happen for real at some point soon.

The basic approach I've taken is to create a "core" mvvmcross portable library:


This single project contains 90% of the mvx code.

The code that doesn't fit into this is all platform specific and interface driven - i.e. it's things like the platform specific views, navigation and container code; or platform specific services like file IO, GPS/location information, launchers and choosers, etc. This code is now moved to small platform specific library projects:




The Binding and Dialog projects for now remain untouched - that's OK because they were never shared by the "core" projects any way - so they are always platform specific and there's no advantage in making those portable.

Moving on the sample projects, well the core of these can now be made portable:


So there is only one "core" project shared between all three ui projects - which is NICE :)


However, there are some problems currently…

  • I've not quite finished! I've got the tutorial sample up and running, but there are still a few platform specific injection objects to make before all the samples will run... and there's lots more testing needed:
    • A Json object
    • A Native Color object
    • A Visibility Color object
  • ObservableCollections are a bit unpleasant to use - INotifyCollectionChanged doesn't exist as a portable interface :/ Because of this any kind of observable collection will need to be wrapped for presentation on wp7
  • ValueConverters are a bit unpleasant to use – IValueConverter doesn't exists as a portable interface :/  Because of this all value converters need to be wrapped before use on wp7
  • I've no idea how this would work in WinRT yet – there will definitely be reflection and interface issues in .net 4.5
  • I don't know what the next version (v2) of the portable class libraries will look like yet!
  • The monotouch and monodroid visual studio tooling isn't working nicely yet – you can't yet reference a portable library project from mt and md, you can only reference a compiled assembly – which means you can't do multi-platform refactoring.
  • Forcing the core projects to be portable may be too limiting... the list of assemblies you can now reference is small.... 

I need to think about this some more.... I think portable class libraries is probably the right direction moving forwards - in the long term! But it's not all upside....

Thursday, April 19, 2012

Wow - PlayStationSuite Open Beta - C# on the PS Vita

Someone tweeted about this -  http://www.playstation.com/pss/developer/index_e.html

So I downloaded it and had thirty minutes of playtime :)

Here's a video of my experience: http://youtu.be/FSZl1-FvUgE





Firstly I played with the UI Composer (designer) - and set up a tip calc like display (like the one in https://github.com/slodge/MvvmCross/ for MonoTouch, MonoDroid, WP7 and WinRT)

It was easy to do - just drag and drop the UI elements, then set their properties, including the generated variable name to use.

When finished, I just hit "Build" in the designer - this spits out:
  • a language csv resource file
  • a C# wrapper for that resource file
  • a scene.cs file - just a partial class with a constructor - this then becomes your "view controller" file for you to edit as you please
  • a scene.composer.cs file - this contains the generated code for the rest of the partial class - basically lots of layout code which matches what you drew in the designer


With that done I then I opened the main PSS Studio (looks and feels like MonoDevelop)

In this studio I:
- ran the new project wizard
- followed the simple instructions in the bundled help file to add the high level ui reference to the project and to add a little code (3 lines?) to help it render
- used project|add to add the files generated above
- tweaked the BuildAction Property for the Csv file to 'content'
- used the monodevelop editor to add the code for tipCalc - this was normal C# code:





using System;
using System.Collections.Generic;
using Sce.Pss.Core;
using Sce.Pss.Core.Imaging;
using Sce.Pss.Core.Environment;
using Sce.Pss.HighLevel.UI;
 
namespace PssUI1
{
    public partial class Scene1 : Scene
    {
        public Scene1()
        {
            InitializeWidget();
   HookThingsUp();
  }
  
  private void HookThingsUp()
  {
   SliderPercent.ValueChanged += (s, e) => {
    TipPercentText.Text = ((int)e.Value).ToString();
    Recalc();
   };
   TipPercentText.TextChanged += (s, e) => {
    SliderPercent.Value = int.Parse(TipPercentText.Text);
    Recalc();
   };
   TotalText.TextChanged += (s, e) => {
    Recalc();
   };
   Recalc();
  }
  
  private void Recalc()
  {
   var total = double.Parse(TotalText.Text);
   var tip = SliderPercent.Value * total / 100.0;
   total += tip;
   this.TipLabel.Text = tip.ToString();
   this.TotalLabel.Text = total.ToString(); 
  } 
    }
}


That was it!

Then I could hit F5 and the code ran in a PS Vita simulator:

That was it!

:) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :) :)

 
For a full blow by blow video: 
http://youtu.be/FSZl1-FvUgE


Really impressed - good job Mono (Xamarin?) and Sony - really good job :)

Sunday, April 15, 2012

video of me talking MvvmCross at wpug - MonoTouch, MonoDroid, WP7 and WinRT MVVM - also... the internet is full of kittens



Not the best audio quality - sorry

Also had some techical issues with the projector resolution... and ran out of time - I blame Matt - he asked me for an hour, then cut me down to 45 minutes on the day!

http://vimeo.com/39019207

Friday, March 30, 2012

Slides from my talk at @DevEvening this week

Similar talk to last week - just thinned down a bit (not everyone in the room was a mobile dev) and also I had slightly longer to talk and managed to pace it better.

Monday, March 26, 2012

Some HTML, Javascript, Jquery, D3.js and CoffeeScript magic - a bit like an html pivotviewer

I put this demo together last week for a school project -  http://slodge.com/teach/

It uses all sorts of html and js goodness inside and it's definitely at prototype stage - but I'm thinking about ways it could grow and change....

Ideally I'd quite like to get access to raw data from school SIMS databases. I will investigate further - but I am not paying GBP5000 for an SDK

MvvmCross slides from my @wpug talk last week

Slides from my @wpug talk last week - will shorten them for this week's DevEvening talk - always learning :)

Saturday, March 24, 2012

Update on MvvmCross - SQLBits conference app

I've been working on a lot of Mvvm on MonoTouch, MonoDroid and WP7 recently - and I've added a bit of WinRT too. 

I've built an Mvvm framework - mvvmcross for this - and it enables code sharing and databinding acoss all the platforms.

As an example app, I've just built and released the SQL Bits conference app. Source code is on https://github.com/slodge/MvvmCrossConference and screenshots are below:

On WP7:


On Android:


On iOS:


All of these apps are **Native apps** using MvvmCross on top of WP7 SDK, MonoTouch and MonoDroid

Monday, February 20, 2012

MvvmCross - Mvvm Across WP7, MonoDroid and MonoTouch

This is just a quick intro post for now... a more full story will follow when I get a bit more of that "spare time" thing, including time to write a few more samples.

I've recently been working on a big cross-platform mobile project targeting Wp7, Android and iPhone. As an inspiration for this we started using the MonoCross platform (http://code.google.com/p/monocross/) although we quickly discovered that MVVM rather than MVC was the way we wanted to go, especially as we were working WP7-first.

To enable this project, we've built our own MVVM framework - MvvmCross - available under a MS-PL license on GitHub at https://github.com/slodge/MvvmCross 

Explaining the framework is going to take a little time... and so will have to wait for a longer series of posts. However, as a quick introduction, the Customer Management sample currently builds and runs across the three major platforms -  https://github.com/slodge/MvvmCross/tree/master/Sample%20-%20CustomerManagement 

This sample has:

As a detailed example, consider the details view for a Customer.


Interested? Confused? Want to know more?

Well the source code is there to play with... and I will post some more samples and some more info soon... possibly on a blog with better code formatting!

One warning though... some of the code still needs a little finishing... especially the Touch/Dialog integration - only a few Elements are currently bound. If anyone wants to help... please let me know!

Friday, January 27, 2012

DropShadow and "glow" on WP7

Doing background glow on WP7...

Proper blog post to follow


And the source is... to follow... soon....

Saturday, November 19, 2011

MonoCross - a different kind of WP7 project approach

Just thought I'd drop a note about MonoCross. The first Wp7 code was only made available this week and so I've only had a few days to play with it. So far I'm finding it fascinating as an alternative way of thinking about how to construct an app.

I know not everyone is doing multiplatform... and I'm already finding that MonoCross gets in the way of some MVVM and data binding stuff, but I'm also finding that there are some very interesting parts to the way MX approaches development - in particular:

  • MX splits the Model and Controller out into one class library, then puts the Views into the app project
  • MX Views are ultimately PhoneApplicationPage's but you inherit via an MXView<TModel> class - it's quite nice that this means you always get a Model to use
  • The navigation framework intercepts the calls to "routes" like "{Controller}/{Action}/{Id}" - so you no longer have to navigate to urls like "Views/EditThing.xaml?ThingId=12" and the navigation framework also takes care of the Model creation/selection for you.

There's plenty of "rough parts" in there - plenty that will get done differently in the future (e.g. there are static class and static member variables everywhere - Mx desparately needs an injection of IoC) and I'm not sure how blendable this approach is - but overall it's very interesting to see an application structured differently - something other than yet another Mvvm platform.

If you're interested, check it out on http://bit.ly/smT0Di

Stuart

P.S. Just in case you were wondering - I've nothing to do with the MX project - it's got some sort of book publisher behind it. I'm just one of the first 1.0 users (I think!)

Tuesday, November 15, 2011

Using MXTabActivityView in MonoCross (MonoDroid flavour)

1. In your application project, add your model - this model will be *shared* by all views within the tabs, plus also shared by the parent tabview itself:
    public class FirstModel
    {
        public List<string> Items1 { get; set; }
        public List<string> Items2 { get; set; }
        public FirstModel()
        {
            Items1 = new List<string>()
                        {
                            "one",
                            "two",
                            "three"
                        };
            Items2 = new List<string>()
                        {
                            "hello",
                            "world",
                            "monocross"
                        };
        }
    }
  
2. Again in your application project, add your controller:
    public class FirstController : MXController<FirstModel>
    {
        public override string Load(Dictionary<string, string> parameters)
        {
            Model = new FirstModel();
            return ViewPerspective.Default;
        }
    }
3. Finally in the application project, make sure you have a route setup for the controller - e.g. a default route like:
            NavigationMap.Add("", new Controllers.FirstController());
4. In your Android container, add the activity views which will sit inside the tabs - e.g.:
    [Activity(Label = "First View!")]
    public class FirstView : MXListActivityView<FirstModel>
    {
        public override void Render()
        {
            ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items1.OrderBy(x => x).ToList() );
        }
    }
and:
    [Activity(Label = "Second View!")]
    public class SecondView : MXListActivityView<FirstModel>
    {
        public override void Render()
        {
            ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items2 );
        }
    }
5. In your Android container project, set up your tab activity view - this is a bit like http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout
Set up the xml resource - e.g.:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <LinearLayout
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:padding="5dp">
    <TabWidget
        android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
    </FrameLayout>
  </LinearLayout>
</TabHost>
Also, add the tab icons if you want them (see notes in http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout)
Then for the MXTabActivityView:
    [Activity(Label = "A TabView!")]
    public class TabView : MXTabActivityView<FirstModel>
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.TabHost);
            TabHost.TabSpec spec;     // Resusable TabSpec for each tab
            Intent intent;            // Reusable Intent for each tab
            // Create an Intent to launch an Activity for the tab (to be reused)
            intent = new Intent(this, typeof(FirstView));
            intent.AddFlags(ActivityFlags.NewTask);
            // Initialize a TabSpec for each tab and add it to the TabHost
            spec = TabHost.NewTabSpec("first");
            spec.SetIndicator("First", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
            spec.SetContent(intent);
            TabHost.AddTab(spec);
            intent = new Intent(this, typeof(SecondView));
            intent.AddFlags(ActivityFlags.NewTask);
            spec = TabHost.NewTabSpec("second");
            spec.SetIndicator("Second", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
            spec.SetContent(intent);
            TabHost.AddTab(spec);
       }
        public override void Render()
        {
           // nothing to do here currently!
        }
    }
}
6. That's it! run and enjoy :)

Wednesday, November 09, 2011

Storage scopes cannot be created when _AppStart is executing.

If you see this error when running ASP.Net MVC apps:

Storage scopes cannot be created when _AppStart is executing.


Then don't panic  - it seems this is just a Cassini problem - if you switch across to IIS express or to a real IIS server then the problem doesn't exist

(phew)