Monday, June 03, 2013

MvvmCross Android app with dynamic fragments

It’s not much different than implementing the app with Java, except using the MvvmCross MvxXXXX classes.
Let’s do a simple exercise: have an activity loading a fragment by code behind.
Here’s the code we need:

1. a MvxFragmentActivity derived class.  It is the corresponding to Android’s FragmentActivity class

[Activity(Label = "View for FirstViewModel")]
public class FirstView : MvxFragmentActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.FirstView);
this.AddChildView ();
}
void AddChildView()
{
var childView = new ChildView () {
ViewModel = new ChildViewModel()
};
var fm = this.SupportFragmentManager;
var ft = fm.BeginTransaction ();
ft.Add (Resource.Id.childViewHost, childView, "childView");
ft.Commit ();
}


2. a corresponding Android layout for it: FirstView.axml
  it needs to have a host widget for the fragment, let’s say a FrameLayout called childViewHost
<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">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/childViewHost" />
</FrameLayout >

 
  3. a MvxFragment derived class. Note the MvvmCross BindingInflate method which makes binding work in the fragment
public class ChildView : MvxFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(Resource.Layout.ChildView, null);
}
}
4. a corresponding Android layout  for it: ChildView.axml. Let’s have a textbox bound to the ViewModel’s property
<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">

<TextView
local:MvxBind="Text Hello"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/textView2" />
</LinearLayout>



Friday, May 24, 2013

ActionBarSherlock in Xamarin Android targeting Android 2.1

ActionBarSherlock is a library which is an extension of the ActionBar in Android. ActionBar appeared in Android 4.

Besides being an extension, this library works for version previous to Android 4, starting from Android 2.1

 

First, we need to build the ActionBarSherlock from scratch using Eclipse. (I had also to install ‘Android SDK Tools’ using the Android SDK Manger).

Second, we need to create a Xamarin Java Binding Library, which will create a bridge library for Xamarin based on the ActionBarSherlock Android library.

For these two steps, follow instructions from http://www.craigsprogramming.com/2012/07/actionbarsherlock-with-mono-for-android.html

To test the app, in the app’s Activit1, just use the sample  code also posted there (use the code from TabActivity class).

 

In order to target Android 2.1:

1. Change properties of the ActionBarSherlockBindings project to have Android minimum version 2.1

2. For the app, also change properties to have Android minimum version 2.1 (in Visual Studio, right click on project, Properties and from the dialog, it’s in the Application tab, ‘Minimum Android to target’)

3. On the app, we need to change it to target Android 4. This is specified in the AndroidManifest.xml file of the app

If it does not exist, in Visual Studio, go to the app properties, and click on ‘Android Manifest’ Tab and click to generate the file.

Once done, UI appears with options for the manifest,  set ‘Target API level’ to 14.

 

Also,  once I targeted Android 2.1, I had to make few changes in the sample code for it to work.

Some classes need to be replaced with classes from the Android.Support.V4.App (like Fragment) and a constant (ActionBar.NavigationModeTabs instead of ActionBar_Sherlock.ActionBarSherlock.ActionBarNavigationMode.Tabs)

Now the app can be tested on an Android 2.1 device or emulator.

Wednesday, May 22, 2013

First app with Xamarin Android and MVVMCross – gotchas

1. After installing Xamarin, create a new ‘Visual C# / Android / Android Application’ using Visual Studio, say ‘DemoApp.Android’ but have the solution called ‘DemoApp’.

2. Add an ‘Visual C# / Windows / Portable Class Library’ called DemoApp.Core.
   First select ‘Windows Phone 7.5 and later’ and then ‘Mono Android’ and ‘MonoTouch’. Note that Xamarin frameworks become available only if you select ‘Windows Phone 7.5 and later’

3. Make sure you have the latest NuGet installed. For this, in Visual Studio, go to Help \ About Microsoft Visual Studio.
image

4. Using NuGet, search for ‘mvvmcross’ and add ‘MVVMCross Hot Tuna Starter Pack’ to BOTH the DemoApp.Android and DemoApp.Core
In the DemoApp.Android, it creates a SplashScreen activity and layout, and a layout and a view in FirstView.axml and FirstView.cs respectively.
In the DemoApp.Core, it creates a FirstViewModel view model.

6. In DemoApp.Android, delete the Activity1.cs and Resources/Layout/Main.axml.

7. Run. It should run OK at this point.

Saturday, February 16, 2013

Saving state in Windows Phone 8 emulator

http://sviluppomobile.blogspot.ro/2013/01/saving-windows-phone-8-emulator-state.html

http://blogs.msdn.com/b/devfish/archive/2012/11/27/what-the-hyper-v-wp8-sdk-emulator-and-hyper-v-insights.aspx

 

Steps:

1. Export virtual machine just in case something bad happens.

2. Run your app from Visual Studio as you normally do OR open the emulator from Hyper-V

3. IMPORTANT: If you started emulator from Visual Studio, close Visual Studio, right click on the virtual machine and click Reset. This will make the virtual machine snapshot you will save next usable from Visual Studio.

4. Customize the Windows Phone OS as you want

5. Create a snapshot

6. Rename the snapshot with the same name as the parent (for example: ‘snapshot.720x1280.1024’)

7. Delete parent (DO NOT select Delete Snapshot Subtree)

9. Run emulator from Visual Studio.

Saturday, February 02, 2013

Windows Phone versions, Windows and Visual Studio versions

On https://dev.windowsphone.com/en-us/downloadsdk are listed all the Windows Phone SDKs.

 

SDK 7.1

Targets devices with Windows Phone 7.0 and Windows Phone 7.5

Windows® Vista® (x86 and x64) with Service Pack 2 – all editions except Starter Edition

Windows 7 (x86 and x64) – all editions except Starter Edition

Visual Studio 2010 SP1

 

SDK 8.0

Targets devices with Windows Phone 8 and Windows Phone 7.5

Windows 8 64-bit (x64) client versions

Windows Phone 8 Emulator:

Windows 8 Pro edition or greater

Requires a processor that supports Second Level Address Translation (SLAT) http://www.petri.co.il/check-cpu-slat-support.htm

Visual Studio 2012

 

SDK 7.8

Adds two new emulator images to your existing Windows Phone SDK installation. This update supports both the Windows Phone SDK 7.1 and the Windows Phone SDK 8.0. Using this update, you can provide the Windows Phone 8 Start screen experience in your Windows Phone 7.5 apps. You can also test how your apps will run on Windows Phone 7.8 devices.

It’s for both SDK 7.1 or SDK 8 to enable developing for Windows Phone 7.5

Tuesday, January 15, 2013

Asynchrounous programming aka async and await support in Windows, Windows RT and Windows Phone

The new async/await syntax of C# 5 is natively supported in WinRT, .NET 4.5 and Windows Phone 8. Up until 22 Oct 2012 it was additionally available for .NET 4.0 and Silverlight 5 via the Async Targeting Pack from June 2012.

On 22 Oct 2012, Microsoft pre-released a package called Microsoft.Bcl.Async additionally for Silverlight 4, Windows Phone 7.5 and, what's probably most surprising, also for Portable Class Libraries targeting all these platforms:

Using async/await without .NET Framework 4.5:

To add a reference to the updated NuGet Package, right click the project, select “Manage Package References” and search for Microsoft.Bcl.Async. Make sure you selected the “Online” tab on the left hand side and the top left drop down says “Include Prerelease”.

Tuesday, January 08, 2013

WCF Data Services + oData + Entity Framework + Silverlight + Telerik simple application

At the time writing this article, WCF Data Services(previously known as ADO.NET Data Services) ships separately from .NET Framework and are distributed by NuGet.

This means, the namespace used is in the form Microsoft.Data.Service.* and not System.Data.Service* (like in .NET Framework). The new release supports oData v3, while the previous release of WCF Data Services existing in .NET Framework supports oData v1 and v2.

This is described here: http://msdn.microsoft.com/en-us/data/ee720179

The Telerik suite has a nice support for WCF Data Services by the RadDataServiceDataSource class, which is able to bind the data from WCF Data Service to the UI.

http://www.telerik.com/help/silverlight/raddataservicedatasource-overview.html

One problem is Telerik was built against the .NET Framework support for WCF Data Services, not against the assemblies distributed by NuGet.

Read more about this here: http://www.telerik.com/community/forums/silverlight/dataservice-datasource/raddataservicedatasource-problem-visual-2012.aspx

 

Steps to create the app:

1. Create a new Silverlight 5 application using Web Application project setting, and suppose the name of the app is SilverlightApplication1

The next steps refer to the web application:

2. I wanted to have a code behind class for the generated SilverlightApplication1TestPage.aspx, so I added a SilverlightApplication1TestPage.aspx.cs class, and in the SilverlightApplication1TestPage.aspx I added:

CodeBehind="SilverlightApplication1TestPage.aspx.cs" Inherits="SilverlightApplication1.Web.SilverlightApplication1TestPage"

Also, I made SilverlightApplication1TestPage to derive from System.Web.UI.Page

3. Add references to System.Data.Services, and System.Data.Services.Client to add support for WCF Data Services.

Also, rigth click on the web project and choose “Manage NuGet packages”. In the top right search box, search for Entity Framework and when found, click on Install button. It will add a reference to EntityFramework assembly.

4. Create a class for an entity called User:

[DataServiceKey("Id")]
[DataServiceEntity]
public class User
{
    [Key]
    public virtual int Id { get; protected set; }
    public virtual string FirstName { get; protected set; }
    public virtual string LastName { get; protected set; }
}

The DataServiceKey and DataServiceEntity attribute need to be set to tell WCF Data Services which is the Id property of the class entity.

5. Create a class derived from DbContext, UserContext

public class UserContext : DbContext
    {
        public DbSet<User> Users
        {
            get;
            set;
        }

        public UserContext(string connString) : base(connString)
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new UserMapping());
            base.OnModelCreating(modelBuilder);
        }
    }

We can expose the User entity by the WCF Data Service using a public property returning a DbSet of that entity

The DbContext constructor accepts a string which represents the connection string to the database

6. Add a UserMapping class which implements the mapping of the User entity to database, so for Entity Framework to know how to do it

public class UserMapping : EntityTypeConfiguration<User>

{
        public UserMapping()
        {
            this.HasKey(t => t.Id);
            this.Property(t => t.FirstName).IsRequired().HasMaxLength(50);
            this.Property(t => t.LastName).IsRequired().HasMaxLength(50);
        }
    }

7. Right click on the web app project, and choose Add New Item/click on Web/WCF Data Service and choose UserService.svc as the name.

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class UserService : DataService<ObjectContext>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            config.UseVerboseErrors = true;
        }

        protected override ObjectContext CreateDataSource()
        {
            var connString = ConfigurationManager.ConnectionStrings["DBConnString"].ConnectionString;
            var context = ((IObjectContextAdapter)new UserContext(connString)).ObjectContext;
            context.ContextOptions.ProxyCreationEnabled = false;
            return context;
        }
    }

The ServiceBehavior attribute makes the web-service to include the exception in the fault details. It is important when debugging.

Fiddler is good to debug web-service issues and this attribute will make the exceptions visible in the response.

SetEntitySetAccessRule is important to set rights on entities.

TestQueryableSL is the name of the connection string to the database

8.  Add the following to the web.config:

<connectionStrings>
    <add name="DBConnString"
         connectionString="Server=YourPCName;Database=Test;Trusted_Connection=True"
         providerName="System.Data.SqlClient"/>
      </connectionStrings>

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>

You should have a database called Test. If not, open SQL Server Management, and add a new database called Test.

In the Silverlight app:

9. Add a new class UserDataCtx:

public class UserDataCtx : UserContext
{
    public UserDataCtx()
        : base(new Uri("
http://localhost:4232/UserService.svc", UriKind.RelativeOrAbsolute))
    {
    }
}
Instead of 4232 port, use the port from right click on Web app project/ Web tab/Use Visual Studio Development Server/Specific port

This class is required in order to pass the Uri to the UserContext class

 

10. In MainPage.xaml add:

xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:l="clr-namespace:SilverlightApplication1"

<Grid x:Name="LayoutRoot"
         Background="White">
       <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="Auto" />
       </Grid.RowDefinitions>
       <telerik:RadDataServiceDataSource Name="customersDataSource"
                                         QueryName="Users"
                                         AutoLoad="True">
           <telerik:RadDataServiceDataSource.DataServiceContext>
               <l:UserDataCtx />
           </telerik:RadDataServiceDataSource.DataServiceContext>
       </telerik:RadDataServiceDataSource>
       <telerik:RadGridView Grid.Row="0"
                            ItemsSource="{Binding DataView, ElementName=customersDataSource}"
                            IsBusy="{Binding IsBusy, ElementName=customersDataSource}"
                            ShowGroupPanel="False" />
       <telerik:RadDataPager Grid.Row="1"
                             Source="{Binding DataView, ElementName=customersDataSource}"
                             PageSize="10" />
   </Grid>

11. Right click on the Silverlight project and add a new service reference. Click on the arrow button from Discover button, and choose ‘Services in this solution’

You should see UserService.svc in the list and selected.

In the Namespace text box, choose the name DataServices

12. Add reference to the Telerik.Windows.Controls/Data/DataServices/GridView/Input  and Telerik.Windows.Data