<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Intersoft Solutions Corporate Blog &#187; Tips and Tricks</title>
	<atom:link href="http://blog.intersoftsolutions.com/category/tips-and-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.intersoftsolutions.com</link>
	<description>All about development productivity – ASP.NET, Silverlight, WPF, iOS, Android, Windows Phone, Windows 8</description>
	<lastBuildDate>Sat, 21 Apr 2018 06:57:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.33</generator>
	<item>
		<title>Using Crosslight Location Service in iOS 8</title>
		<link>http://blog.intersoftsolutions.com/2016/08/using-crosslight-location-service-in-ios-8/</link>
		<comments>http://blog.intersoftsolutions.com/2016/08/using-crosslight-location-service-in-ios-8/#comments</comments>
		<pubDate>Mon, 15 Aug 2016 06:05:56 +0000</pubDate>
		<dc:creator><![CDATA[Yudhiy Ariawan]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Location Service]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=8204</guid>
		<description><![CDATA[Using Crosslight Location Service Location service provides a streamlined way to access location API that conforms to each the device’s platform. In order to get the current location of the device, we use following snippet code: This method translate to, get the current location of [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2016/08/IMG_0221-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="NSLocationWhenInUseUsageDescription" style="float:right; margin:0 0 10px 10px;" /><div id="full-height-container">
<div id="splitter">
<div id="splitter-content">
<div id="main" class="aui-page-panel">
<div id="content" class="page view">
<div class="wiki-content">
<div class="contentLayout2">
<div class="columnLayout two-right-sidebar" data-layout="two-right-sidebar">
<div class="cell normal" data-type="normal">
<div class="innerCell">
<h1>Using Crosslight Location Service</h1>
<p>Location service provides a streamlined way to access location API that conforms to each the device’s platform. In order to get the current location of the device, we use following snippet code:</p><pre class="crayon-plain-tag">this.MobileService.Location.GetCurrentLocation(LocationAccuracy.Best,
    (locationResult) =&gt;
    {
        if (locationResult.Error == null)
		{
		}
        else
		{
		}
    });</pre><p>This method translate to, get the current location of the device, with best accuracy.</p>
</div>
<div class="innerCell">
<div id="full-height-container">
<div id="splitter">
<div id="splitter-content">
<div id="main" class="aui-page-panel">
<div id="content" class="page view">
<div class="wiki-content">
<div class="contentLayout2">
<div class="columnLayout single" data-layout="single">
<div class="cell normal" data-type="normal">
<div class="innerCell">
<h1>Problem: My app doesn&#8217;t returns current location. Why?</h1>
<p>Some of you might found out that the code fails silently. You will get no error or warning, but it will never get a location update. The app will never even ask for permission to use location.</p>
<p>It took me a while until I found that we need to add a key to Info.plist and request authorization from the location manager asking it to start. It&#8217;s an iOS 8 (and later) related issue. The key, <em>NSLocationWhenInUseUsageDescription</em>, is required when you request authorization for location services. If this key is not present, the system ignores your request and prevents your app from using location services.</p>
<h1>Solution: Asking user&#8217;s permission to access their location</h1>
<p>So we&#8217;ll need to add the key to the Info.plist file. It takes a string which is a description of why the app need location services. We can enter a string like &#8220;Location is required to find out where you are&#8221;.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	...
	&lt;key&gt;NSLocationWhenInUseUsageDescription&lt;/key&gt;
	&lt;string&gt;Location is required to find out where you are.&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre><p>Save the changes and re-run the app. Your app will now requesting permission by showing a popup.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2016/08/IMG_0221.png"><img class="alignnone size-medium wp-image-8205" src="http://blog.intersoftsolutions.com/wp-content/uploads/2016/08/IMG_0221-169x300.png" alt="NSLocationWhenInUseUsageDescription" width="169" height="300" /></a></p>
<p>Hopefully this post may helps developers using location services on iOS 8 (or later). If you have questions or feedback please feel free to submit in the comments section below.</p>
<p>Regards,<br />
Yudi</p>
<p>&nbsp;</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2016/08/using-crosslight-location-service-in-ios-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with Crosslight Collection Views and Grid Views</title>
		<link>http://blog.intersoftsolutions.com/2015/11/getting-started-with-crosslight-collection-views-and-grid-views-5/</link>
		<comments>http://blog.intersoftsolutions.com/2015/11/getting-started-with-crosslight-collection-views-and-grid-views-5/#comments</comments>
		<pubDate>Thu, 26 Nov 2015 09:32:18 +0000</pubDate>
		<dc:creator><![CDATA[Arief]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[kb-how-to-article]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[collection view]]></category>
		<category><![CDATA[Cross Platform]]></category>
		<category><![CDATA[grid view]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[menu]]></category>
		<category><![CDATA[navigation]]></category>
		<category><![CDATA[springboard]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=5483</guid>
		<description><![CDATA[Hi guys, Arief here from the Intersoft Consultant team. Today I will talk about how to use iOS Collection View and Android Grid View in order to create a beautiful cross-platform navigation menu. At the end of this tutorial, you&#8217;ll learn how to use the collection view in [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Result-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="Result" style="float:right; margin:0 0 10px 10px;" /><p>Hi guys, Arief here from the Intersoft Consultant team. Today I will talk about how to use iOS Collection View and Android Grid View in order to create a beautiful cross-platform navigation menu. At the end of this tutorial, you&#8217;ll learn how to use the collection view in your Crosslight applications, which looks similar to the following illustration.</p>
<p><img class="alignnone wp-image-5524 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Result.png" alt="Result" width="865" height="726" /></p>
<h1>Introduction</h1>
<p>Collection View / Grid View (will be referred as <em>Collection View</em> from now on) is a very versatile user interface. As a matter fact, both <em>iOS</em> and <em>Android</em> have always been using it as a native pattern for Springboard (iOS home) as well as lots of other Android launchers. Nowadays those trends start to spread throughout business apps considering how user-friendly and eye-pleasing when compared to the plain old list view.</p>
<p>If you are interested in creating a gorgeous and cool business apps, using collection view is a must! In this tutorial, I will guide you step by step how you can create collection view using the <em>Crosslight style</em>.</p>
<p>Here are the steps that you need to follow:</p>
<ul>
<li>Core Preparation</li>
<li>Assets Preparation</li>
<li>Designing Android Grid View</li>
<li>Designing iOS Collection View</li>
<li>Capturing Selection</li>
</ul>
<p>Without further ado, let&#8217;s get started!</p>
<h1>Preparing the Project</h1>
<p>The first thing you&#8217;ll need is, of course, the project itself. Start by creating a new project using Crosslight Project Wizard and choose the <strong>Blank</strong> template. To do this, from Visual Studio 2012 and upwards, choose <strong>New</strong>, <strong>Project</strong>. From the dialog that appears, choose <strong>Crosslight</strong> and choose to create a new Crosslight application with the <strong>Blank</strong> template. For the purposes of this tutorial, we&#8217;ll name this project: <strong>CollectionView. </strong>Now that you have your project ready, let&#8217;s move on.</p>
<h1>Core Preparation</h1>
<p>Here are several things you need to prepare at the project Core level:</p>
<ul>
<li>Prepare the ViewModel</li>
<li>Prepare the BindingProvider</li>
</ul>
<h2>Prepare the ViewModel</h2>
<p>Begin by creating a new ViewModel in <strong>CollectionView.Core/ViewModels</strong> folder. Simply right-click on the <strong>ViewModels</strong> folder and choose <strong>Add</strong>, <strong>New Item</strong>. We will be repeating this method several times in later sections to add new items to our project, so keep this in mind.</p>
<p><img class="alignnone wp-image-5285 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled1.png" alt="Adding New Item" width="619" height="356" /></p>
<p>Crosslight also ships with built-in item templates that are integrated with Visual Studio, so you can quickly create Crosslight classes right within Visual Studio or Xamarin Studio. In the next dialog that appears, choose <strong>Visual C</strong>#, <strong>Crosslight</strong>, then choose <strong>Crosslight List View Model</strong>. Name this ViewModel as <strong>CollectionViewModel</strong>.</p>
<p><img class="alignnone wp-image-5286 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled2.png" alt="CrosslightListViewModel" width="955" height="582" /></p>
<p>Copy-paste these codes to the newly-created <strong>CollectionViewModel.cs</strong>:</p><pre class="crayon-plain-tag">using Intersoft.Crosslight;
using Intersoft.Crosslight.ViewModels;
using System.Collections.Generic;

namespace CollectionView.Core.ViewModels
{
    public class CollectionViewModel : ListViewModelBase
    {
        #region Constructors

        public CollectionViewModel()
        {
			List items = new List();

			items.Add(new NavigationItem("Ride", typeof(SimpleViewModel)) { Image = "CrosstransRide.png" });
			items.Add(new NavigationItem("Delivery", typeof(SimpleViewModel))  { Image = "CrosstransDeliver.png" });
			items.Add(new NavigationItem("Food", typeof(SimpleViewModel))  { Image = "CrosstransFood.png" });
			items.Add(new NavigationItem("Shop", typeof(SimpleViewModel))  { Image = "CrosstransShop.png" });

			this.SourceItems = items;
        }

        #endregion
    }
}</pre><p>Let&#8217;s take a quick look at the above code. In the constructor of the <strong>CollectionViewModel</strong>, we initialize a list of <strong>NavigationItems</strong> that holds the navigation menus. <strong>NavigationItem</strong> is a very useful class provided by Crosslight that you can utilize to create a menu, as it holds all the common properties you need to create a navigation item. All you have to do is simply populate it with the menu title, image/icon name, and the target <em>ViewModel</em> as navigation target.</p>
<h2>Preparing the BindingProvider</h2>
<p>Next step would be adding a new <strong>Crosslight List Binding Provider</strong> under your <strong>CollectionView.Core/BindingProviders </strong>folder. Give it a name of <strong>CollectionBindingProvider.cs.</strong></p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled3.png"><img class="alignnone wp-image-5289 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled3.png" alt="CrosslightListBindingProvider" width="955" height="582" /></a></p>
<p>And change the code to the following:</p><pre class="crayon-plain-tag">using Intersoft.Crosslight;

namespace CollectionView.Core.BindingProviders
{
    public class CollectionViewBindingProvider : BindingProvider
    {
        #region Constructors

        public CollectionViewBindingProvider()
        {
            ItemBindingDescription itemBinding = new ItemBindingDescription
            {
                DisplayMemberPath = "Title",
                ImageMemberPath = "Image",
                NavigateMemberPath = "Target"
            };

            this.AddBinding("GridView", BindableProperties.ItemsSourceProperty, "Items");
            this.AddBinding("GridView", BindableProperties.ItemTemplateBindingProperty, itemBinding, true);
            this.AddBinding("GridView", BindableProperties.IsBatchUpdatingProperty, "IsBatchUpdating");
            this.AddBinding("GridView", BindableProperties.SelectedItemProperty, "SelectedItem", BindingMode.TwoWay);
            this.AddBinding("GridView", BindableProperties.SelectedItemsProperty, "SelectedItems", BindingMode.TwoWay);
            this.AddBinding("GridView", BindableProperties.IsEditingProperty, "IsEditing", BindingMode.TwoWay);

            this.AddBinding("RefreshButton", BindableProperties.RefreshCommandProperty, "RefreshCommand");

            // navigation
            //this.AddBinding("TableView", BindableProperties.DetailNavigationTargetProperty, new NavigationTarget(typeof(TViewModel)), true);

            // edit commands
            this.AddBinding("AddButton", BindableProperties.CommandProperty, "AddCommand");

            this.AddBinding("DeleteButton", BindableProperties.CommandProperty, "DeleteCommand");
            this.AddBinding("DeleteButton", BindableProperties.CommandParameterProperty, "SelectedItems");
        }

        #endregion
    }
}</pre><p>In the above code, we simply comment out the <strong>DetailNavigationTargetProperty</strong>, as it won&#8217;t be needed because our goal is only to create a navigation menu. It will be needed if you want to create <a href="http://developer.intersoftsolutions.com/display/crosslight/Master-Detail+Navigation">Master-Detail Navigation</a>. We also assign the <strong>MemberPaths </strong>with the properties from <strong>NavigationItem</strong>, such as <strong>ImageMemberPath</strong> for the icon, <strong>DisplayMemberPath</strong> for displaying the title, and <strong>NavigateMemberPath </strong>for the target <em>ViewModel</em> menu. To learn more about Crosslight Binding Provider, check out this <a href="http://developer.intersoftsolutions.com/display/crosslight/Understanding+Binding+Providers">link</a>.</p>
<p><img class="alignnone wp-image-5291 size-medium" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled4-300x71.png" alt="Cave Johnson, We'll done here!" width="300" height="71" /></p>
<p>Your Core is up and ready. Let&#8217;s prepare our assets next.</p>
<h1>Assets Preparation</h1>
<p>Previously in the Binding Provider, you have already specified the <strong>Image</strong> property in <strong>NavigationItem</strong> from <em>ViewModel</em> which contains the filename for the .png file that we will use. When you bind it to the <em>BindableProperties.ImageProperty</em> or <em>ImageMemberPath</em>, it will find the appropriate files to use in<strong> CollectionView.Android/Resources/drawable</strong> or in <strong>CollectionView.iOS/Resources. </strong>So you need to put <a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Image.zip">these files</a> inside both folders because we will be using it for our app&#8217;s interface.<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/CrosstransFood.png"><br />
</a></p>
<p>Tip: Make sure to optimize the size of your image files. In some phones, images with humongous file size will be ignored and they won&#8217;t show. Okay, since you have finished preparing the assets, let&#8217;s continue to Android GridView!</p>
<h1>Designing Android GridView</h1>
<p>Designing a view for Android is relatively easy and simple. In overall, we&#8217;ll be doing these tasks:</p>
<ul>
<li>Create an Activity for <strong>CollectionActivity</strong>.</li>
<li>Create the view layout.</li>
<li>Define the <strong>ContentLayoutId</strong> and <strong>ItemLayoutId</strong>.</li>
</ul>
<p>To start, simply add a new item and use <strong>Crosslight Android Activity</strong> to get started. Put it inside the <strong>CollectionView.Android/Activities </strong>folder and name it <strong>CollectionActivity.cs</strong>.</p>
<p><img class="gr-progress alignnone wp-image-5293 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled5.png" alt="Crosslight Android Activity" width="955" height="582" /></p>
<p>After your <strong>CollectionActivity</strong> is created, change the contents of the class to the following code.</p><pre class="crayon-plain-tag">using Android.App;
using Intersoft.Crosslight;
using Intersoft.Crosslight.Android;

namespace CollectionView.Android.Activities
{
    [Activity(Label = "Menu")]
    [ImportBinding(typeof(CollectionBindingProvider))]
    public class CollectionActivity : GridActivity
    {
        public override ListViewInteraction InteractionMode
        {
            get{ return ListViewInteraction.Navigation; }
        }

        protected override int ContentLayoutId
        {
            get{ return Resource.Layout.CollectionLayout;}
        }

        protected override int GridItemLayoutId 
        {
	       get{ return Resource.Layout.ItemLayout; }
	    }

        protected override void InitializeView()
        {
            base.InitializeView();
            this.GridView.NumColumns = 2;
        }
    }
}</pre><p>We need to replace the <strong>Activity</strong> with <strong>GridActivity</strong>,<strong> </strong>in<strong> </strong>which then you have more properties to override: <strong>ListViewInteraction</strong>. By overriding the <strong>ListViewInteraction</strong> into <strong>ListViewInteraction.Navigation</strong>, it allows the user to use the grid as a navigation button when an item is tapped.</p>
<p><strong>ContentLayoutId</strong> is also overridden since we want to customize the appearance of our GridView, which we will do in just a moment. The <strong>ItemLayoutId </strong>is overridden to customize the item layout to be used with the GridView. Both <strong>ContentLayoutId</strong> and <strong>ItemLayoutId</strong> refers to Android layout files which exist in the <strong>CollectionView.Android/Resources</strong> folder.</p>
<p>Since we only have two columns for this scenario, we can simply provide the number of columns to show in the overridden <strong>InitializeView</strong> method by setting <strong>this.GridView.NumColumns </strong>to <strong>2</strong>. The advantage of using this method is: you actually don&#8217;t need to specify the width of the Grid. The <em>GridActivity</em> automatically adjusts the optimal number of items by taking account the viewport width.</p>
<p>Earlier, we&#8217;ve specified the <strong>ContentLayoutId</strong> and <strong>ItemLayoutId</strong> in our Activity. Now let&#8217;s create those layouts. You will need to create two layouts inside <strong>CollectionView.Android/Resources/layout </strong>folder using <em>Android Layout</em> item template. We will name it <strong>CollectionLayout.axml</strong> &amp; <strong>ItemLayout.axml.</strong></p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidLayout1.png"><img class="alignnone size-full wp-image-5531" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidLayout1.png" alt="AndroidLayout" width="955" height="582" /></a></p>
<p>Here&#8217;s the code for <strong>CollectionLayout.axml</strong> and <strong>ItemLayout.axml</strong> respectively.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/CrosstransBg"
    android:minWidth="25px"
    android:minHeight="25px"&gt;
    &lt;LinearLayout
        android:orientation="horizontal"
        android:layout_marginBottom="25dp"
        android:layout_marginTop="50dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout1"
        android:gravity="center_horizontal"&gt;
        &lt;ImageView
            android:src="@drawable/CrosstransLogo"
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:id="@+id/imageView1" /&gt;
    &lt;/LinearLayout&gt;
    &lt;GridView
        android:minWidth="25px"
        android:minHeight="25px"
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:verticalSpacing="20dp"
        android:horizontalSpacing="20dp"
        android:id="@+id/GridView" /&gt;
&lt;/LinearLayout&gt;</pre><p>From the designer&#8217;s view, the <strong>CollectionLayout </strong>looks like the following:</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/CollectionLayout1.png"><img class="alignnone size-full wp-image-5544" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/CollectionLayout1.png" alt="CollectionLayout" width="728" height="574" /></a></p>
<p>and here&#8217;s the contents for <strong>ItemLayout.axml</strong>:</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minWidth="25px"
    android:minHeight="25px"
    android:background="#CC2368C0"
    android:gravity="center_horizontal"&gt;
    &lt;LinearLayout
        android:orientation="vertical"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/linearLayout1"
        android:gravity="center_horizontal|center_vertical"&gt;
        &lt;ImageView
            android:src="@android:drawable/ic_menu_gallery"
            android:scaleType="centerCrop"
            android:adjustViewBounds="true"
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:id="@+id/ImageView" /&gt;
    &lt;/LinearLayout&gt;
    &lt;TextView
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:id="@+id/TextLabel"
        android:gravity="center_horizontal" /&gt;
&lt;/LinearLayout&gt;</pre><p>From the designer&#8217;s view, it looks like this:</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ItemLayout.png"><img class="alignnone size-full wp-image-5545" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ItemLayout.png" alt="ItemLayout" width="726" height="569" /></a></p>
<p>In summary, what I do in <strong>CollectionLayout.axml</strong> is setting the background for the page, add a header, and provide enough spacing between GridView items. The most important things to note is I&#8217;ve defined the GridView id,  <strong>@+id/GridView. </strong>The will be the reference that we defined in <em>BindingProvider</em> to the property in <em>ViewModel, </em>so make sure the id name is right!</p>
<p>We will be doing a similar task with<strong> ItemLayout.axml</strong>, where we assign both <strong>ImageView</strong> to the <strong>Image</strong> Property in <em>ViewModel</em> and <strong>TextView</strong> to <strong>Title</strong> Property in <em>ViewModel</em>. By default, Crosslight provides two built-in ids for showing an image and a text for item template, which has the name <em>ImageView</em> and <em>TextLabel</em> respectively. But if you want to add additional view elements to the item template, then you can simply add a new binding definition in the binding provider like this which must be done in BindingProvider:</p><pre class="crayon-plain-tag">itemBinding.AddBinding ("CustomView", BindableProperties.TextProperty, "Title");</pre><p>Run the project. You should get a result similar to the following:</p>
<div style="width: 300px; " class="wp-video"><!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->
<video class="wp-video-shortcode" id="video-5483-1" width="300" height="0" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_09_11_14.mp4?_=1" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_09_11_14.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_09_11_14.mp4</a></video></div>
<p>Next, let&#8217;s create the iOS version.</p>
<h1>Designing iOS CollectionView</h1>
<p>Similar to Android, building <strong>CollectionView</strong> on iOS follows a pretty similar path:</p>
<ul>
<li>Create a ViewController for MainCollectionView.</li>
<li>Create the cell and the header.</li>
<li>Set the outlets.</li>
</ul>
<p>Let&#8217;s start from the ViewController. Add a new item using <strong>Crosslight</strong><strong> iOS Collection View Controller </strong>template<strong> </strong>and put it inside your <strong>CollectionView.iOS/ViewControllers </strong>folder and name it <strong>MainCollectionView.cs</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-5.16.58-PM.png"><img class="alignnone wp-image-5505 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-5.16.58-PM.png" alt="MainViewController" width="721" height="550" /></a></p>
<p>This is the code for the ViewController.</p><pre class="crayon-plain-tag">using CollectionView.ViewModels;
using CollectionView;
using Intersoft.Crosslight;
using Intersoft.Crosslight.iOS;
using Foundation;
using UIKit;

namespace CollectionView.iOS
{
	[Register ("MainCollectionView")]
	[ImportBinding (typeof(CollectionBindingProvider))]
	public class MainCollectionView : UICollectionViewController
	{
		#region Constructors

		public MainCollectionView ()
			: base ("MainCollectionView", null)
		{
		}

		#endregion

		#region Properties

		public override UIViewTemplate CellTemplate {
			get { return new UIViewTemplate (CollectionViewCell.Nib); }
		}

		public override CollectionViewInteraction InteractionMode {
			get { return CollectionViewInteraction.Navigation; }
		}

		public override bool ShowSectionHeader {
			get { return true; }
		}

		public override UIViewTemplate SectionHeaderTemplate {
			get { return new UIViewTemplate(CollectionHeader.Nib); }
		}

		#endregion

		#region Methods

		protected override void InitializeView ()
		{
			base.InitializeView ();

			this.NavigationItem.Title = "Home";
                        UIImageView backView = new UIImageView(UIImage.FromFile ("CrosstransBg.png")); 
                        backView.ContentMode = UIViewContentMode.ScaleAspectFill; 
                        this.CollectionView.BackgroundView = backView;
			// Register Views
			this.RegisterViewIdentifier ("GridView", this.CollectionView);
		}

		#endregion
	}
}</pre><p>Let&#8217;s take a look at some of the overridden methods and properties.</p>
<ul>
<li><strong>CellTemplate</strong>: This property is the equivalent of Android&#8217;s <strong>ItemLayoutID</strong>, which will define the view to be used as navigation item inside the Collection View.</li>
<li><strong>InteractionMode</strong>: This method is the equivalent of Android&#8217;s <strong>ListViewInteraction</strong>, that defines the interaction when users tap on the navigation item.</li>
<li><strong>SectionHeader &amp; SectionHeaderTemplate</strong>: It will be used to specify the header for the Collection View.</li>
<li><b>InitializeView</b>: This method is called when the view is initialized. Here, we set the background view of the Collection View. Afterward, <em>this.RegisterViewIdentifier (&#8220;GridView&#8221;, this.CollectionView); </em>is used to associate the Collection View with the <strong>GridView</strong> view identifier to be used by the Binding Provider.</li>
</ul>
<p>Now your view controller is done! Next, we&#8217;ll create the <em>CollectionView</em> <em>Header</em> and <em>Cells</em>. Inside your <strong>CollectionView.iOS/Views</strong>, add 2 new items: <strong>Crosslight iOS Collection Cell</strong>, we will name it <strong>CollectionViewCell.cs </strong>(feel free to choose between iPhone or iPad) and <strong> Crosslight iOS Collection View Group Header</strong> which we will name it <strong>CollectionHeader.cs.</strong></p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.33.53-AM.png"><img class="alignnone wp-image-5506 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.33.53-AM.png" alt="CollectionViewCell" width="719" height="548" /></a></p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.34.49-AM.png"><img class="alignnone wp-image-5507 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.34.49-AM.png" alt="CollectionHeader" width="719" height="549" /></a></p>
<p>If you check back your <strong>MainCollectionView.cs</strong>, you can see that both <strong>CollectionViewCell.Nib</strong> <strong>&amp; CollectionHeader.Nib are</strong> now detected. The Nib represents both .cs files that we&#8217;ve created before. However, we won&#8217;t touch any codes, instead we will play around with the layout using iOS XCode.</p>
<p>Let&#8217;s first open the <strong>MainCollectionView.xib</strong> inside your <strong>CollectionView.iOS/Views</strong> using Apple XCode. Inside the Document Outline, you can select <em>File&#8217;s Owner</em>, then the Identity Inspector will change according to what  you selected. Specify the Custom Class as <strong>MainCollectionView</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/asdsadsa.png"><img class="alignnone size-full wp-image-5508" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/asdsadsa.png" alt="Files Owner" width="261" height="128" /></a>  <a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.46.08-AM.png"><img class="alignnone wp-image-5509 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-27-at-10.46.08-AM.png" alt="MainViewControllerClass" width="257" height="434" /></a></p>
<p>Using the Connections Inspector, control + drag the <em>view</em> from Outlets to the Collection View to set the outlet, as shown in the following illustration.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/MainCollectionView.png"><img class="alignnone size-large wp-image-5546" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/MainCollectionView-1024x231.png" alt="MainCollectionView" width="604" height="136" /></a></p>
<p>Then, in the File Inspector, turn off Auto Layout.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/turnoffautolayout1.png"><img class="alignnone wp-image-5513 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/turnoffautolayout1.png" alt="turnoffautolayout" width="260" height="391" /></a></p>
<p>In the Size Inspector, specify the cell&#8217;s width and height, also adjusting the auto-resizing behaviors so that it will layout nicely when the device is rotated.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/CollectionViewConfiguration.png"><img class="alignnone wp-image-5514 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/CollectionViewConfiguration.png" alt="CollectionViewConfiguration" width="260" height="665" /></a></p>
<p>Now you are done configuring your <strong>MainCollectionView.xib.</strong></p>
<p>Let&#8217;s continue to <strong>CollectionViewCell.xib</strong>, in this case, you don&#8217;t need to worry about  your <strong>File&#8217;s Owner</strong>,  Simply drag and drop a <strong>Label</strong> and <strong>ImageView</strong> from the Object Library to the view.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/viewchoice.png"><img class="alignnone wp-image-5515 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/viewchoice.png" alt="viewchoice" width="262" height="491" /></a></p>
<p>Select your Label (or anything in your designer interface), Press the conjoined circle button on the right top. A panel with codes will appear, this is the <strong>Assistant Editor</strong> which will help you create Binding without having you to code anything.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ConjoinedCircle.png"><img class="alignnone wp-image-5516 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ConjoinedCircle.png" alt="ConjoinedCircle" width="698" height="421" /></a></p>
<p>Next, let&#8217;s set the outlets using the Assistant Editor. Select your <strong>CollectionViewCell.m</strong> and change it to <strong>CollectionViewCell.h</strong>, control + drag your <strong>Label</strong> into the panel and give it <strong>TextLabel</strong> as a name, then set the <strong>ImageView</strong> outlet with the name of <strong>ImageView</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ctrldrop.png"><img class="alignnone wp-image-5517 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ctrldrop.png" alt="ctrldrop" width="881" height="417" /></a></p>
<p>You need to turn off the auto layout from both image, label, and their parent to use auto resizing. Here&#8217;s what I&#8217;ve done to each of them:</p>
<ul>
<li><strong>View</strong>: Change the background color, turn on the horizontal and vertical scaling so that it won&#8217;t grow or shrink when the display rotates.</li>
<li><strong>TextLabel</strong>: Change the alignment to the middle,  Pin it to the bottom using auto resizing and change the width to 120 and height to 50</li>
<li><strong>ImageView</strong>: Change the view mode to Aspect fit, turn on the horizontal and vertical arrow inside auto-resizing, and changes the width and height to 60</li>
</ul>
<p>In <strong>CollectionHeader.xib</strong>, what we do is just drag and drop an ImageView. Here are the settings for ImageView:</p>
<ul>
<li>Change the image with CrosstransLogo.png,</li>
<li>View Mode to Aspect Fit,</li>
<li>Width = 150,</li>
<li>Turn on the horizontal and vertical arrow inside auto resizing</li>
</ul>
<p>Here is the result:</p>
<div style="width: 300px; " class="wp-video"><video class="wp-video-shortcode" id="video-5483-2" width="300" height="0" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Crosstransios.mp4?_=2" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Crosstransios.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Crosstransios.mp4</a></video></div>
<p>Your app is pretty much done, but we still ned to capture what user has selected.</p>
<h1>Capturing Selection</h1>
<p>In this section, we&#8217;ll learn how to capture selection made when the user taps on any of the navigation items.</p>
<p>If you recall earlier, we&#8217;ve defined how our <em>CollectionView</em> should navigate, which is done in our <em>BindingProvider </em>in the <strong>NavigateMemberPath </strong>inside using <strong>ItemBindingDescription</strong>.</p><pre class="crayon-plain-tag">ItemBindingDescription itemBinding = new ItemBindingDescription
            {
                DisplayMemberPath = "Title",
                ImageMemberPath = "Image",
                NavigateMemberPath = "Target"
            };</pre><p>As you are aware, each <em>MemberPath</em> represents the component of our menu. In fact, it also contains the whole data associated with the specific Item you choose from the list that you have created in your <em>ViewModel</em> back then.</p><pre class="crayon-plain-tag">public CollectionViewModel()
        {
			List items = new List();

			items.Add(new NavigationItem("Ride", typeof(SimpleViewModel)) { Image = "CrosstransRide.png" });
			items.Add(new NavigationItem("Delivery", typeof(SimpleViewModel))  { Image = "CrosstransDeliver.png" });
			items.Add(new NavigationItem("Food", typeof(SimpleViewModel))  { Image = "CrosstransFood.png" });
			items.Add(new NavigationItem("Shop", typeof(SimpleViewModel))  { Image = "CrosstransShop.png" });

			this.SourceItems = items;
        }</pre><p>BindingProvider will obtain the target of your navigation, represented by <em>typeof(SimpleViewModel))</em>. However even though we already successfully navigate,  in our case each of our Item have the same Navigation target. What if we want to know which item/menu is selected? Here is how:</p>
<p>When you navigate to a new <em>ViewModel</em>, the <strong>Navigated</strong> method is called in the target <em>ViewModel</em>, and it contains the <strong>sender</strong> value which holds the information of the caller <em>ViewModel</em>. For the simplicity of this tutorial, we&#8217;ll change the <em>SimpleViewModel</em> to handle user input. Let&#8217;s change our <strong>SimpleViewModel.cs </strong>(CollectionView.Core/ViewModels folder):</p><pre class="crayon-plain-tag">using Intersoft.Crosslight;
using Intersoft.Crosslight.Input;
using Intersoft.Crosslight.ViewModels;

namespace CollectionView.ViewModels
{
    public class SimpleViewModel : ViewModelBase
    {
        #region Fields

        private string _footerText;
        private string _greetingText;
        private string _newText;

        #endregion

        #region Properties

        public string FooterText
        {
            get { return _footerText; }
            set
            {
                if (_footerText != value)
                {
                    _footerText = value;
                    OnPropertyChanged("FooterText");
                }
            }
        }

        public string GreetingText
        {
            get { return _greetingText; }
            set
            {
                if (_greetingText != value)
                {
                    _greetingText = value;
                    OnPropertyChanged("GreetingText");
                }
            }
        }

        public string NewText
        {
            get { return _newText; }
            set
            {
                if (_newText != value)
                {
                    _newText = value;
                    OnPropertyChanged("NewText");
                }
            }
        }

        public DelegateCommand ShowToastCommand { get; set; }

        #endregion

        #region Constructors

        public SimpleViewModel()
        {
            IApplicationContext context = this.GetService().GetContext();
            if (context.Platform.OperatingSystem == OSKind.Android)
                this.GreetingText = "Hello Android from Crosslight!";
            else if (context.Platform.OperatingSystem == OSKind.WinPhone)
                this.GreetingText = "Hello WinPhone from Crosslight!";
            else if (context.Platform.OperatingSystem == OSKind.WinRT)
                this.GreetingText = "Hello WinRT from Crosslight!";
            else if (context.Platform.OperatingSystem == OSKind.iOS)
                this.GreetingText = "Hello iOS from Crosslight!";

            this.FooterText = "Powered by Crosslight®";
            this.ShowToastCommand = new DelegateCommand(ShowToast);
        }

        #endregion

        #region Methods

        public override void Navigated (NavigatedParameter parameter)
        {
            if (parameter.Sender is CollectionViewModel) 
            {
                this.ToastPresenter.Show("You are choosing: " + (parameter.Sender as CollectionViewModel).SelectedItem.Title);
            }
        }

        private void ShowToast(object parameter)
        {
            this.ToastPresenter.Show("You entered: " + this.NewText);
            this.GreetingText = this.NewText;
        }

        #endregion
    }
}</pre><p>The menu that user chooses will be represented by <strong>SelectedItem </strong>and there are two things to note here: <strong>SelectedItem</strong> actually obtained from the<strong> sender ViewModel</strong> which is from <em>CollectionViewModel.cs</em> and <strong>SelectedItem</strong> actually the default property provided from <em>CollectionViewModel</em> implementing the <strong>ListViewModelBase</strong>. In this case, we will show a toast presenter to indicate which menu the user has chosen, by obtaining the <strong>Title</strong> of <strong>SelectedItem </strong>and show it using Toast Presenter.</p>
<p>Also, If you put a breakpoint in the highlighted line above and inspect the <strong>NavigatedParameter</strong>,<strong> </strong>you can see from the shot below that it holds lots of information not only the <strong>SelectedItem </strong>but the whole CollectionViewModel.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Content.png"><img class="alignnone wp-image-5500 size-full" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Content.png" alt="Debugger Content" width="571" height="488" /></a></p>
<p>You will use this neat trick to accomplish a lot of cool things using Crosslight, so don&#8217;t forget to save this favourite this blog for later uses. Okay, now let&#8217;s run our project!</p>
<p>Wait&#8230; should we also change the Android and iOS? <strong>No need at all</strong> using Crosslight you only need to change it in Core and it will be applied to each platform, very convenient! Here is the result:</p>
<div style="width: 300px; " class="wp-video"><video class="wp-video-shortcode" id="video-5483-3" width="300" height="0" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_14_23_41.mp4?_=3" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_14_23_41.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_14_23_41.mp4</a></video></div>
<div style="width: 300px; " class="wp-video"><video class="wp-video-shortcode" id="video-5483-4" width="300" height="0" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/crosstransfull.mp4?_=4" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/crosstransfull.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/crosstransfull.mp4</a></video></div>
<h1>Wrapping Up</h1>
<p>With Crosslight, you will never have to worry about the code behind the scene. However, in  this session, I want to emphasize the customizability of Crosslight, using minimal effort and codes we already successfully create a simple and gorgeous navigation menu. I believe the next steps for you is to discover more about Crosslight features and we still have more tutorials coming in the futures! So stay tuned with us and have fun!</p>
<p>You can find the source code for this post here: <a href="http://git.intersoftsolutions.com/projects/CT/repos/crosslightcollectionview/browse">http://git.intersoftsolutions.com/projects/CT/repos/crosslightcollectionview/browse</a></p>
<p>See you in the next post,<br />
Arief Handany</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/11/getting-started-with-crosslight-collection-views-and-grid-views-5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_09_11_14.mp4" length="4544727" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Crosstransios.mp4" length="1532667" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2015_11_27_14_23_41.mp4" length="13983430" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/crosstransfull.mp4" length="3605056" type="video/mp4" />
		</item>
		<item>
		<title>Creating Dockable View for iOS and Android</title>
		<link>http://blog.intersoftsolutions.com/2015/11/creating-dockable-view-for-ios-and-android/</link>
		<comments>http://blog.intersoftsolutions.com/2015/11/creating-dockable-view-for-ios-and-android/#comments</comments>
		<pubDate>Mon, 23 Nov 2015 11:51:49 +0000</pubDate>
		<dc:creator><![CDATA[Nicholas Lie]]></dc:creator>
				<category><![CDATA[2015 R2]]></category>
		<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[kb-how-to-article]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[2015 r2]]></category>
		<category><![CDATA[dockable]]></category>
		<category><![CDATA[dockable view]]></category>
		<category><![CDATA[footer]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[Mobile Development]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=5182</guid>
		<description><![CDATA[In my previous post, I&#8217;ve shown you how to use a header and footer with custom views in a list/table view. Now, what if I want to show a dockable view at the bottom of the screen? Let’s take the previous sample a bit further [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-1.05.53-PM-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="Screen Shot 2015-11-23 at 1.05.53 PM" style="float:right; margin:0 0 10px 10px;" /><p>In my previous <a href="http://blog.intersoftsolutions.com/2015/11/adding-header-and-footer-for-ios-tableview-and-android-listview/">post</a>, I&#8217;ve shown you how to use a header and footer with custom views in a list/table view. Now, what if I want to show a dockable view at the bottom of the screen? Let’s take the previous sample a bit further to look like the following.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.06.12-PM.png"><img class="alignnone size-large wp-image-5196" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.06.12-PM-1024x853.png" alt="Screen Shot 2015-11-23 at 2.06.12 PM" width="604" height="503" /></a></p>
<h1>Starting off</h1>
<p>To start off, I’ll just copy off the previous sample. If you haven’t read the <a href="http://blog.intersoftsolutions.com/2015/11/adding-header-and-footer-for-ios-tableview-and-android-listview/" target="_blank">previous post</a> on how to provide header and footer to your TableView / ListView, it is highly recommended for you to do so before continuing.</p>
<p>If you have done so, let’s move on.</p>
<h1>Creating dockable view on iOS</h1>
<p>To create the dockable view on iOS, you’ll need to do the following:</p>
<ul>
<li>Preparing custom table root view</li>
<li>Modifying the View</li>
<li>Modifying the View Controller</li>
</ul>
<h2>Preparing custom table root view</h2>
<p>To provide the custom table root view, you’ll need to create a new <strong>Crosslight iOS View for iPhone</strong>, which is accessible from the Item Templates, available after you’ve successfully installed Crosslight.</p>
<p>Right click on the Views in HeaderAndFooter.iOS/Views folder and select <strong>Add</strong>, <strong>New Item.</strong></p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.09.45-PM.png"><img class="alignnone size-full wp-image-5197" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.09.45-PM.png" alt="Screen Shot 2015-11-23 at 2.09.45 PM" width="970" height="408" /></a></p>
<p>Then choose, <strong>Crosslight iOS View for iPhone</strong>. Give it a name of <strong>CustomTableRootView</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.13.23-PM.png"><img class="alignnone size-large wp-image-5198" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.13.23-PM-1024x786.png" alt="Screen Shot 2015-11-23 at 2.13.23 PM" width="604" height="464" /></a></p>
<p>First, let’s try to create a the custom table root view. Open the <strong>CustomTableRootView.xib </strong>in Xcode Interface Builder.</p>
<h3>Adding the Docked View</h3>
<p>Drag a new <strong>View</strong> from the <strong>Object library</strong>, set the outlet as <strong>DockedView</strong>, and provide the following constraints:</p>
<ul>
<li><strong>Horizontal Space </strong><strong>Constraint</strong>: from <em>Superview.Trailing</em> equal to the <em>View.Trailing</em> with the following values.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.08-AM.png"><img class="alignnone size-large wp-image-5199" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.08-AM-1024x619.png" alt="Screen Shot 2015-11-23 at 11.28.08 AM" width="604" height="365" /></a></li>
<li><strong>Vertical Space Constraint</strong>: from <em>Superview.Bottom</em> equal to the <em>View.Bottom</em> with the following values.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.10-AM.png"><img class="alignnone size-large wp-image-5200" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.10-AM-1024x619.png" alt="Screen Shot 2015-11-23 at 11.28.10 AM" width="604" height="365" /></a></li>
<li><strong>Horizontal Space Constraint</strong>: from <em>DockedView.Leading</em> equal to the <em>Superview.Leading</em> with the following values.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.12-AM.png"><img class="alignnone size-large wp-image-5201" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-11.28.12-AM-1024x619.png" alt="Screen Shot 2015-11-23 at 11.28.12 AM" width="604" height="365" /></a></li>
</ul>
<p>Now that the docked view is ready, let’s drag a <strong>Label</strong>, set the outlet as <strong>TxtHeader</strong>, and drag a button, set the outlet as <strong>BthHeader</strong>. Both of them are given the previous outlet names, so that no code changes will be required in the <strong>BindingProvider</strong> side. If you wish, you can set the following constraints:</p>
<ul>
<li>Give the DockedView a height of 45.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-1.05.53-PM.png"><img class="alignnone size-large wp-image-5202" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-1.05.53-PM-1024x619.png" alt="Screen Shot 2015-11-23 at 1.05.53 PM" width="604" height="365" /></a></li>
<li>Vertically align the label as well as the button.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.19.44-PM.png"><img class="alignnone size-large wp-image-5203" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.19.44-PM-1024x774.png" alt="Screen Shot 2015-11-23 at 2.19.44 PM" width="604" height="457" /></a></li>
<li>Give an inner padding of 20.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.20.49-PM.png"><img class="alignnone size-large wp-image-5204" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.20.49-PM-1024x767.png" alt="Screen Shot 2015-11-23 at 2.20.49 PM" width="604" height="452" /></a></li>
</ul>
<p>That’s pretty much it. Let’s modify the View a bit.</p>
<h2>Modifying the View</h2>
<p>Let’s open the <strong>CustomTableRootView.cs </strong>and modify that a bit by adding a new <strong>ResizeTableView</strong> method.</p><pre class="crayon-plain-tag">using System;
using System.Drawing;
using System.Linq;
using CoreGraphics;
using Foundation;
using UIKit;

namespace HeaderAndFooter.iOS
{
    public partial class CustomTableRootView : UIView
    {
        #region Constructors

        public CustomTableRootView(IntPtr handle) : base(handle)
        {
        }

        #endregion

        #region Fields

        public static readonly UINib Nib = UINib.FromName("CustomTableRootView", NSBundle.MainBundle);

        #endregion

        #region Methods

        public static CustomTableRootView Create()
        {
            return (CustomTableRootView) Nib.Instantiate(null, null)[0];
        }


        internal void ResizeTableView(nfloat top)
        {
            var tableView = this.Subviews.FirstOrDefault(o =&gt; o is UITableView);
            tableView.Frame = new CGRect(0, top, tableView.Bounds.Width, this.Bounds.Height - top - this.DockedView.Bounds.Height);
        }

        #endregion
    }
}</pre><p>Here, we prepare a handy method to resize the table view when the view is used, called <strong>ResizeTableView</strong>. By calling this method, the <strong>TableView</strong> that contains this dock view will have its bounds re-adjusted. This is done so that the scrolling container in the <strong>TableView</strong> does not exceed the docked view. Take a closer a look at the contents of the method.</p>
<p>In line 36, we first search for the TableView that is added as a subview of the <strong>ViewController</strong>. In line 37, we set a new bounds for it, not changing the width at all, but just by adjusting the height by taking account the <strong>DockedView.Bounds.Height</strong> as well.</p>
<h2>Modifying the View Controller</h2>
<p>Next, open up the <strong>MainViewController.cs</strong>. Here’s the contents.</p><pre class="crayon-plain-tag">using CoreGraphics;
using Foundation;
using HeaderAndFooter.ViewModels;
using Intersoft.Crosslight;
using Intersoft.Crosslight.iOS;
using UIKit;

namespace HeaderAndFooter.iOS.ViewControllers
{
    [Register("MainViewController")]
    [ImportBinding(typeof(MainBindingProvider))]
    public class MainViewController : UITableViewController&lt;MainViewModel&gt;
    {
        #region Properties

        public override UIViewTemplate FooterViewTemplate
        {
            get { return new UIViewTemplate(CustomFooter.Nib); }
        }

        public override TableViewInteraction InteractionMode
        {
            get { return TableViewInteraction.Navigation; }
        }

        public override bool ShowGroupHeader
        {
            get { return false; }
        }

        public override UITableViewStyle TableViewStyle
        {
            get { return UITableViewStyle.Plain; }
        }

        public override bool UseCustomRootView
        {
            get { return true; }
        }

        #endregion

        #region Methods

        protected override void InitializeView()
        {
            base.InitializeView();

            // set navigation title
            this.NavigationItem.Title = "Crosslight App";
        }

        protected override UIView GetCustomRootView()
        {
            return CustomTableRootView.Create();
        }

        public override void ViewWillLayoutSubviews()
        {
            base.ViewWillLayoutSubviews();

            // adjust tableview frame based on top layout guide	
            ((CustomTableRootView)this.View).ResizeTableView(this.TopLayoutGuide.Length);
        }

        #endregion
    }
}</pre><p>Here, we removed the overridden property for <strong>HeaderViewTemplate</strong>, since we’re going to use the new <strong>DockedView</strong> to replace the header. Therefore, we then override a new property called <strong>UseCustomRootView</strong> and return true.</p>
<p>After we&#8217;ve done that, we then override the <strong>GetCustomRootView()</strong> method to return the CustomTableRootView that we’ve just created by calling <strong>CustomTableRootView.Create()</strong>;</p>
<blockquote><p>The custom root view is one of the unique features introduced in Crosslight&#8217;s advanced <a href="http://developer.intersoftsolutions.com/display/crosslight/iOS+Table+View">UITableViewController</a>. It allows you to easily replace the root view with a custom one with just a few property sets, while still retaining the developer experience and automatic binding feature. In the case above, when <strong>UseCustomRootView</strong> is returning a true value, the <strong>GetCustomRootView</strong> method will be automatically called when the controller is initializing.</p></blockquote>
<p>Lastly, we override the <strong>ViewWillLayoutSubviews</strong> method. This method is called when a new subview is added to the <strong>ViewController</strong>, which can be done at any time, whether during <strong>ViewController</strong> creation or programmatically adding a subview at runtime, therefore, when the <strong>DockedView</strong> is added, we then call our handy method to resize the TableView so that the scrolling container wouldn’t “bleed” past the <strong>DockedView</strong>.</p>
<p>That’s it. Run the project and you should get the result similar to the following video.</p>
<div style="width: 400px; " class="wp-video"><video class="wp-video-shortcode" id="video-5182-5" width="400" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS1.mp4?_=5" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS1.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS1.mp4</a></video></div>
<h1>Creating dockable view on Android</h1>
<p>Now that we’ve finished the iOS version, let’s create the Android version. To create the docakble view on Android, you’ll need to complete the following:</p>
<ul>
<li>Preparing custom layout</li>
<li>Replacing the content layout in Activity</li>
</ul>
<h2>Preparing custom layout</h2>
<p>First things first, let’s create a new Android Layout, and let’s name it <strong>CustomLayout.axml</strong>. To do this, right click on the <strong>HeaderAndFooter.Android/Resources/layout</strong> folder.</p>
<p><img class="alignnone size-full wp-image-5208" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.47.11-PM.png" alt="Screen Shot 2015-11-23 at 2.47.11 PM" width="952" height="516" /></p>
<p>Select <strong>Add</strong>, <strong>New Item</strong>. Under <strong>Android</strong>, select <strong>Layout</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.47.50-PM.png"><img class="alignnone size-large wp-image-5209" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-23-at-2.47.50-PM-1024x785.png" alt="Screen Shot 2015-11-23 at 2.47.50 PM" width="604" height="463" /></a></p>
<p>Provide the layout for the <strong>CustomLayout.axml</strong> as follows.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"&gt;
    &lt;LinearLayout
        android:id="@+id/Footer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical"&gt;
        &lt;LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="1px"
            android:background="#f2f2f2" /&gt;
        &lt;LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"&gt;
            &lt;TextView
                android:id="@+id/TxtHeader"
                android:layout_width="fill_parent"
                android:layout_height="30dp"
                android:layout_weight="1"
                android:gravity="left"
                android:textSize="20sp" /&gt;
            &lt;Button
                android:id="@+id/BtnHeader"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" /&gt;
        &lt;/LinearLayout&gt;
    &lt;/LinearLayout&gt;
    &lt;ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/Footer" /&gt;
&lt;/RelativeLayout&gt;</pre><p>Let’s take a closer look. Here, we’ve used a <strong>RelativeLayout</strong> as the root <strong>ViewGroup </strong>and we’ve added 2 major elements to the <strong>RelativeLayout</strong>, which is a <strong>LinearLayout</strong> that will act as our <strong>DockedView</strong> and <strong>ListView</strong>.</p>
<blockquote><p>At a glance, you might be wondering why the <strong>ListView</strong> is defined after the <strong>LinearLayout</strong>. This is purely for build purposes. The XML parser parses the text from top to bottom. Since in the <strong>ListView</strong>, we’ve defined<strong> android:layout_above=“@id/Footer”,</strong> the build will fail if the LinearLayout is not defined beforehand. Hence, the <strong>ListView</strong> is defined after the <strong>LinearLayout</strong>.</p></blockquote>
<p>One important thing to notice that the <strong>ListView’s</strong> id is set to<strong> @android:id/list</strong>. This conforms the standard method to override the built-in ListActivity&#8217;s layout in native Android development itself. For more information on that topic, click <a href="http://developer.android.com/reference/android/app/ListActivity.html" target="_blank">here</a>. This is done because in the <strong>ListActivity</strong> class, you can reference the <strong>ListView</strong> as simply as calling <strong>this.ListView</strong>, however since you’ve overridden the whole layout, then the <strong>ListView</strong> must be re-referenced this way so that the Android understands. Everything else is just standard Android layouting process.</p>
<h2>Replacing the content layout in Activity</h2>
<p>After the layout is prepared, let’s modify some codes in the Activity. Open up <strong>MainActivity.cs</strong> inside <strong>HeaderAndFooter.Android/Activities</strong> folder and see the contents as follows.</p><pre class="crayon-plain-tag">using Android.App;
using HeaderAndFooter.ViewModels;
using Intersoft.Crosslight;
using Intersoft.Crosslight.Android;

namespace HeaderAndFooter.Android
{
    [Activity(Label = "Crosslight App", Icon = "@drawable/icon")]
    [ImportBinding(typeof(MainBindingProvider))]
    public class MainActivity : ListActivity&lt;MainViewModel&gt;
    {
        #region Properties

        protected override int ContentLayoutId
        {
			get { return Resource.Layout.CustomLayout; }
        }

        protected override int FooterLayoutId
        {
            get { return Resource.Layout.CustomFooter; }
        }

        public override ListViewInteraction InteractionMode
        {
            get { return ListViewInteraction.Navigation; }
        }

        #endregion

        #region Methods

        protected override void InitializeView()
        {
            base.InitializeView();

            this.RegisterViewIdentifier("TableView", this.ListView);
        }

        #endregion
    }
}</pre><p>In the <strong>ContentLayoutId </strong>property, we’ve replaced the old layout to the new <strong>CustomLayout</strong> that we’ve created earlier and we’ve also removed the <strong>HeaderLayoutId</strong>. You’ve completed the Android version. Let’s run this project and you should get the result similar to the following.</p>
<div style="width: 400px; " class="wp-video"><video class="wp-video-shortcode" id="video-5182-6" width="400" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android1.mp4?_=6" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android1.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android1.mp4</a></video></div>
<h1>Wrapping Up</h1>
<p>You’ve seen how easy and elegant it is to provide a dockable view to your table view on iOS as well as list view on Android. Achieving the same task without Crosslight would be really tedious and time consuming. The dockable view also comes with automatic binding support, so you can take advantage of native binding process with whatever layout you have. Nice and simple.</p>
<p>You can find the code to the sample here:<br />
<a href="http://git.intersoftsolutions.com/projects/CT/repos/crosslightdockableview/browse" target="_blank">http://git.intersoftsolutions.com/projects/CT/repos/crosslightdockableview/browse</a>. To use this sample, you’ll need at least <a href="http://git.intersoftsolutions.com/projects/CROS/repos/updates/browse/Crosslight4_0_5000_323" target="_blank">Crosslight build 4.0.5000.323</a> and above.</p>
<p>See you in the next post,<br />
Nicholas Lie</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/11/creating-dockable-view-for-ios-and-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS1.mp4" length="668912" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android1.mp4" length="305590" type="video/mp4" />
		</item>
		<item>
		<title>Redesigning Xamarin Field Service Sample with Crosslight &#8211; Part 1</title>
		<link>http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/</link>
		<comments>http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/#comments</comments>
		<pubDate>Fri, 20 Nov 2015 07:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Nicholas Lie]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reference Samples]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Design Pattern]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[UI Design]]></category>
		<category><![CDATA[UX Design]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Xamarin]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=4878</guid>
		<description><![CDATA[Hi guys, Nicholas here. I’m back with another blog post, this time covering the Xamarin Field Service sample. Many of you have asked: “How can I transform the Xamarin Field Service sample using Crosslight?” And that tickled something in the back of our minds. This [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabList-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="TabList" style="float:right; margin:0 0 10px 10px;" /><p>Hi guys, Nicholas here. I’m back with another blog post, this time covering the <a href="https://xamarin.com/prebuilt/field-service" target="_blank">Xamarin Field Service</a> sample. Many of you have asked: “How can I transform the Xamarin Field Service sample using Crosslight?” And that tickled something in the back of our minds. This could be our next Crosslight reference sample! So we embarked on a quest to transform the Xamarin Field Service completely using Crosslight and see how much we can do about it.</p>
<h1>Tablet-only Design?</h1>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/1446536283_full1.png"><img class=" size-large wp-image-4941 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/1446536283_full1-1024x378.png" alt="1446536283_full" width="604" height="223" /></a></p>
<p style="text-align: center;"><em>Xamarin Field Service on Android, iPad and Windows 8.1</em></p>
<p>Before delving further, we need to take a step back and have a good look on overall UI and UX design of this app. When talking about cross-platform, yes, it would be valid to say that this app works cross-platform. But it only works on tablets. Why can’t the design be brought to the phone as well?</p>
<p>Let me share with you some of the design quirks found in the app, and how we decided to transform the experience in overall. We’re not talking about any code stuff first in this post. Just pure, plain UX, then we’ll move on to code sharing aspects in the next post.</p>
<h2>The Assignments Screen</h2>
<p>The assignments screen. At a first glance, nothing seems to be wrong with it. So, we decided to add additional swipe gesture touches to it, to change statuses quickly. Overall, I’m totally fine with it.</p>
<h2>The Assignment Detail</h2>
<p>Until it pushes the entire screen to display the assignment detail. Let&#8217;s take a look at Xamarin&#8217;s Field Service push navigation.</p>
<div style="text-align: center;">
<div style="width: 604px; " class="wp-video"><video class="wp-video-shortcode" id="video-4878-7" width="604" height="311" loop="1" autoplay="1" preload="metadata" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iPad-Transition.mp4?_=7" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iPad-Transition.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iPad-Transition.mp4</a></video></div>
<p><em>Xamarin Field Service &#8211; iPad Push Navigation</em></p>
</div>
<p>The transition between the assignments list and the assignment detail screen. It’s quite rare to see an iPad app performs a push navigation in such manner, especially in a list navigation. Most mobile apps will present itself with a SplitView on iPad, in which the push navigation will be contained within itself, not navigating the entire view. This is apparent in several iPad’s default apps, such as Mail, Contacts, Messages and Notes. I’m not saying this design is incorrect. But what if there is a way to enhance the navigation experience, much like the Apple’s native experience?</p>
<p><strong>Problem</strong>: User experiences abrupt changes when navigating to detail view, hindering the user experience.<strong><br />
Objective</strong>: Show the detail view without abrupt, major changes in screen presentation.<br />
<strong>Considerations</strong>: Obviously, we can’t add a SplitView to do that.<br />
<strong>Our solution:</strong> Crosslight Dialog Presenter.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-dialog-presenter.png"><img class="alignnone size-large wp-image-5029" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-dialog-presenter-1024x891.png" alt="ipad-dialog-presenter" width="604" height="526" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; iPad Dialog Presenter</em></p>
<p>The Dialog Presenter is be a perfect candidate to replace the push navigation. By displaying a beautiful translucent modal panel from the right-hand side to the center that covers third-quarter of the screen, we managed to simulate the “content navigation” found in split view apps, enhancing the overall detail navigation experience. To close the dialog presenter, users can simply tap on the left hand side of the screen, outside the dialog presenter.</p>
<blockquote><p>Have you managed to get started with the Dialog Presenter? If not, I’ve covered how to <a href="http://blog.intersoftsolutions.com/2015/11/getting-started-with-crosslight-dialog-presenter/" target="_blank">get started with the Dialog Presenter</a> in another post.</p></blockquote>
<p>Reusing the same view, the dialog presenter&#8217;s content can be easily adapted to iPhone&#8217;s more compact screen and uses simple push navigation, as follows.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iphone-summary1.png"><img class=" wp-image-5020 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iphone-summary1-630x1024.png" alt="iphone-summary" width="300" height="488" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; iPhone Push Navigation</em></p>
<p style="text-align: left;">Crosslight is all about reusability, efficiency and design pattern consistency. You can easily design views that work perfectly in either phone or tablets, thanks to its robust, thoughtfully engineered navigation service.</p>
<h2>Displaying the Navigation Items</h2>
<p>Okay, we’ve managed to solve the list navigation experience. But how about containing all those navigation items in the detail view of our dialog presenter? Currently, we have 7 items: <strong>Summary</strong>, <strong>Map</strong>, <strong>Items</strong>, <strong>Labor Hours</strong>, <strong>Expenses</strong>, <strong>Documents</strong>, <strong>Confirmations</strong>. I’m not including History since it’s not supported by Xamarin just yet.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2navigation1.png"><img class="alignnone wp-image-4991" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2navigation1.png" alt="2navigation" width="700" height="500" /></a></p>
<p style="text-align: center;"><em>Xamarin Field Service &#8211; iPad Navigation List</em></p>
<p><strong>Problem</strong>: The navigation items takes up too much space and exceeds the 5-items-limit for the tabs.<strong><br />
Objective</strong>: Display the navigation items inside the dialog presenter, while still maintaining a native and pleasant iPad UX.<br />
<strong>Considerations</strong>: Can we simplify the navigation items even futher?<br />
<strong>Our solution</strong>: Tabbed navigation.</p>
<p>Up to this point, you might have several objections in mind, such as: “What if Xamarin decided to bring that History menu back up and even adding more modules to the app? Your tabbed solution will not be able to solve that issue, no?” Yes. We admit it won’t be able fit more items inside it, as Apple has provided a maximum threshold of 5 items of the tab controllers.</p>
<p>However, we can improve the navigation item categorization to include lesser items and display them as needed. Remember, as a UI/UX designer, you have to keeps things simple for your users. And contextual. Imagine you’re designing the app for your mom, therefore, you have to keep it as simple as possible.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2navigation2.png"><img class="alignnone wp-image-4992" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/2navigation2.png" alt="2navigation2" width="700" height="774" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; iPad Tabs</em></p>
<p>Our answer was to reduce the number of navigation items into maximum of 5 items: <strong>Summary</strong>, <strong>Items</strong>, <strong>Labor Hours</strong>, <strong>Expenses</strong>, and <strong>Confirmations</strong>. The <strong>Map</strong> and <strong>Documents</strong> can easily fit into the <strong>Summary</strong> tab. It all makes sense, considering that the <strong>Map</strong> and <strong>Documents</strong> do not contain any data entry capabilities and does not require any user interactions whatsoever. In other words, they’re designed to be <em>read-only</em>, which would fit the <strong>Summary</strong> tab. Why use 7 tabs if you can manage with just 5? And here&#8217;s how it looks on the iPhone.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iphonesummary-2.png"><img class=" wp-image-5024 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iphonesummary-2-722x1024.png" alt="iphonesummary-2" width="300" height="425" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; iPhone Tabs</em></p>
<p>As for the <strong>History</strong> problem, since users can&#8217;t perform any data interaction with it, you can simply add a <strong>History</strong> icon button within the <strong>Summary</strong> tab that displays the previous records related with the assignment, or if you would like to separate each the list of <strong>Documents</strong> and list of <strong>History </strong>records, you can introduce a segmented button, like the one found in Apple&#8217;s App Store Purchased screen, especially the &#8220;<strong>All</strong>&#8221; and &#8220;<strong>Not on This iPad</strong>&#8220;.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-app-store-purchased.png"><img class="alignnone size-large wp-image-5023" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-app-store-purchased-1024x776.png" alt="ipad-app-store-purchased" width="604" height="458" /></a></p>
<p style="text-align: center;"><em>App Store &#8211; iPad &#8211; Purchased</em></p>
<h2>The Summary Screen</h2>
<p>When I think of <strong>Summary</strong>, I always assume that the user expects the view to contain <em>read-only</em><b> </b>information. For that same reason, the <strong>Summary</strong> screen is perfect to display static list of items, in which the user can perform only one action upon it.</p>
<p><img class=" wp-image-5039 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/xamarin-map-1024x617.png" alt="xamarin-map" width="700" height="422" /></p>
<p style="text-align: center;"><em>Xamarin Field Service &#8211; iPad &#8211; Summary</em></p>
<p><strong>Problem</strong>: The number of items to be included tab navigation can only contain max. 5 items.<strong><br />
Objective</strong>: Reduce the number of navigation items and display relevant information in a simpler manner.<br />
<strong>Considerations</strong>: Decide which navigation menus that don&#8217;t need user interaction.<br />
<strong>Our solution</strong>: Put <strong>Maps</strong> and <strong>Documents</strong> inside the Summary screen.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-summary-map.png"><img class=" size-large wp-image-5040 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-summary-map-1024x602.png" alt="ipad-summary-map" width="604" height="355" /></a></p>
<p>&nbsp;</p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; Maps and Documents in Summary</em></p>
<p>Therefore, we decide to inject <strong>Map</strong> and <strong>Documents</strong> inside the <strong>Summary</strong> screen. Including the <strong>Map</strong> was pretty simple. We display then <strong>Map</strong> on the top header, along with other relevant information about the customer. If users were to click on the map view, then Apple Maps will be fired up with a placemark showing more details about the location in the form of map annotations. As for the <strong>Documents</strong>, it is achievable simply by adding the documents list at the very bottom of the <strong>Summary</strong> page.</p>
<h2>The Items Screen</h2>
<p>How many times have you encountered an iPad app with adding and editing experience that is not located in the navigation bar? I’m sure, not much. For me, it’s my first time.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/items-old.png"><img class=" wp-image-5031 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/items-old.png" alt="items-old" width="700" height="490" /></a></p>
<p style="text-align: center;"><em>Xamarin Field Service &#8211; Items</em></p>
<p>And because of that, I’m pretty sure this is not Apple’s standard design.</p>
<p><strong>Problem</strong>: The user actions are not part of the navigation bar and it&#8217;s confusing.<br />
<strong>Objective</strong>: Provide a method for the user to display the relevant information as needed.<br />
<strong>Considerations</strong>: What does the user usually expect when perform user actions?<br />
<strong>Our solution</strong>: By removing the sticky header altogether, we&#8217;ve managed to place the user actions where it truly belongs.</p>
<p style="text-align: center;"><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Item-Search.png"><img class="alignnone size-large wp-image-5185" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Item-Search-1024x768.png" alt="Item-Search" width="604" height="453" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; Items</em></p>
<p>The addition and editing of items generally occurs from the navigation bar, in which we have done so with the dialog presenter approach. Since the Items screen is similar to the <strong>Labor Hours</strong> and <strong>Expenses</strong> screen, we’re taking the same approach to both of the screens.</p>
<h2>The Sticky Header</h2>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/xamarin-sticky-header.png"><img class=" wp-image-5034 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/xamarin-sticky-header-1024x878.png" alt="xamarin-sticky-header" width="700" height="600" /></a></p>
<p style="text-align: center;"><em>Xamarin Field Service &#8211; Sticky Header</em></p>
<p><strong>Problem</strong>: With the sticky header gone, what is the best place to put it?<br />
<strong>Objective</strong>: Find an alternative to place the sticky header with global accessibility.<br />
<strong>Considerations</strong>: The information should be globally accessible, anytime, anywhere.<br />
<strong>Our solution</strong>: Provide a header callout that displays the removed information.</p>
<p>In my personal opinion, it’s the &#8220;sticky header” in the content detail view is what breaks the overall iPad experience. This is why we have removed this view and opted to stick it in only the <strong>Summary</strong> view, the correct place where it belongs. Users also do not have to see this information the whole time.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-callout.png"><img class="alignnone size-large wp-image-5035" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-callout-1024x913.png" alt="ipad-callout" width="604" height="539" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; iPad</em></p>
<p>However, if the user wants to see that quick information, he can just tap on the top header anytime and a callout will present the temporary information he needed.</p>
<h2>The &#8220;Active Work&#8221; Indicator/Player</h2>
<p>Before we proceed, we might have forgotten one other thing. The “active work” indicator/player. If you notice, when the assignment is marked as Active, the player pops out from the bottom of the screen to let the user know that the current assignment is active and he can pause at any time. This will count automatically as a new entry in the <strong>Labor Hours</strong> screen.</p>
<p><strong>Problem</strong>: Display globally-available information that shows the current work is active that adheres to Apple&#8217;s standard user experience.<strong><br />
Objective</strong>: Display the “active work” indicator/player in the dialog presenter content detail.<br />
<strong>Considerations</strong>: It has to be global (user should be able to see it all the time). The dialog presenter content is already cramped up. Where would be the correct place to put the view?</p>
<p>Before I present you with our approach to the above problem, I want you to think how to solve this problem. Think of all the possible places and approaches to tackle this problem. And yes, Apple did have this exact same problem in one of their apps. Can you guess what the app is?</p>
<p>Did you come up with any solution to the above problem? If not, let me tell you what <strong>our solution</strong> is: <strong>Apple’s Music Player View</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/applemusic.png"><img class="alignnone wp-image-4998" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/applemusic-1024x652.png" alt="applemusic" width="700" height="446" /></a></p>
<p style="text-align: center;"><em>Apply Music &#8211; Player</em></p>
<p>Think about it. The Music app introduced in iOS 8.4 has this exact same problem. When the music is playing, how can Apple show the user on what music is playing, globally, and whether the user can perform any actions upon it?</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-player.png"><img class=" wp-image-5036 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/ipad-player-1024x884.png" alt="ipad-player" width="700" height="605" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; Active Work View</em></p>
<p>Yes, we dealt with the problem the same way. Both of the solutions are consistent in iPhone and iPad.</p>
<h2>The Confirmation Screen</h2>
<p>The last, but not the least view in the app: the confirmation screen. This screen also presents quite a challenge to be redesigned and optimized.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/9confirm-before.png"><img class=" size-full wp-image-4983 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/9confirm-before.png" alt="9confirm-before" width="938" height="714" /></a></p>
<p style="text-align: center;"><em>Xamarin Field Service &#8211; Confirmation</em></p>
<p>Take a look at the design above. And imagine running it on a phone.<br />
The design is quite tricky to address, since it has one list and a signature pad.</p>
<p><strong>Problem</strong>: The screen&#8217;s design cannot be adapted to phones.<strong><br />
Objective</strong>: Revamp the screen in such a way that will accommodate users running on tablets and phones.<br />
<strong>Considerations</strong>: The vertical-scrolling list might be a problem.<br />
<strong>Our solution</strong>: Change the vertical-scrolling list into a horizontal-scrolling list and add the signature pad directly beneath it.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/8confirmation1.png"><img class=" wp-image-4996 aligncenter" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/8confirmation1-1024x660.png" alt="8confirmation" width="700" height="451" /></a></p>
<p style="text-align: center;"><em>Crosslight Field Service &#8211; Confirmation Screen</em></p>
<p>Therefore, we’ve elegantly redefined how things work in the <strong>Confirmation</strong> screen by making the <em>Photos</em> section acts as a carousel view with <em>Signature Pad</em> placed directly underneath it. This way, it can work on smaller screens like phones.</p>
<h1>How about Android?</h1>
<p>Android fans, do not fret. Let&#8217;s take a look at the Android designs of the Field Service app.</p>
<p>Here&#8217;s a gallery of how it looks on the phone.</p>

<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-expenses-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-Popup-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-Expenses-Popup" data-attachment-id="5041" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-Popup.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-Expenses-Popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-Popup-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-Popup-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-expenses/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-Expenses" data-attachment-id="5042" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-Expenses" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Expenses-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-items-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-popup-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-items-popup" data-attachment-id="5043" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-popup.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-items-popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-popup-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-popup-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-items/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-items" data-attachment-id="5044" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-items" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-items-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-labor-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-Popup-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-Labor-Popup" data-attachment-id="5045" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-Popup.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-Labor-Popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-Popup-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-Popup-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-labor/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-Labor" data-attachment-id="5046" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-Labor" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Labor-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-list/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-list-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-list" data-attachment-id="5047" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-list.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-list" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-list-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-list-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-login/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Login-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-Login" data-attachment-id="5048" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Login.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-Login" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Login-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-Login-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-map/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-map-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-map" data-attachment-id="5049" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-map.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-map" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-map-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-map-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphone-summary/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-summary-150x150.png" class="attachment-thumbnail" alt="AndroidPhone-summary" data-attachment-id="5050" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-summary.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhone-summary" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-summary-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhone-summary-576x1024.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/androidphoneconfirmation/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhoneconfirmation-150x150.png" class="attachment-thumbnail" alt="AndroidPhoneconfirmation" data-attachment-id="5051" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhoneconfirmation.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="AndroidPhoneconfirmation" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhoneconfirmation-169x300.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/AndroidPhoneconfirmation-576x1024.png" /></a>

<p>And here&#8217;s how it looks on Android tablets.</p>

<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabconfirmation/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabConfirmation-150x150.png" class="attachment-thumbnail" alt="TabConfirmation" data-attachment-id="5053" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabConfirmation.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabConfirmation" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabConfirmation-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabConfirmation-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabexpense-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-Popup-150x150.png" class="attachment-thumbnail" alt="TabExpense-Popup" data-attachment-id="5054" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-Popup.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabExpense-Popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-Popup-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-Popup-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabexpense/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-150x150.png" class="attachment-thumbnail" alt="TabExpense" data-attachment-id="5055" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabExpense" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabExpense-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabitem-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabItem-Popup-150x150.png" class="attachment-thumbnail" alt="TabItem-Popup" data-attachment-id="5056" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabItem-Popup.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabItem-Popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabItem-Popup-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabItem-Popup-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tablabor-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-popup-150x150.png" class="attachment-thumbnail" alt="TabLabor-popup" data-attachment-id="5057" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-popup.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabLabor-popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-popup-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-popup-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tablabor/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-150x150.png" class="attachment-thumbnail" alt="TabLabor" data-attachment-id="5058" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabLabor" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLabor-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tablist/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabList-150x150.png" class="attachment-thumbnail" alt="TabList" data-attachment-id="5059" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabList.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabList" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabList-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabList-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tablogin/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLogin-150x150.png" class="attachment-thumbnail" alt="TabLogin" data-attachment-id="5060" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLogin.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabLogin" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLogin-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabLogin-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabmap/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabMap-150x150.png" class="attachment-thumbnail" alt="TabMap" data-attachment-id="5061" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabMap.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabMap" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabMap-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabMap-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabsummary-popup/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-Popup-150x150.png" class="attachment-thumbnail" alt="TabSummary-Popup" data-attachment-id="5062" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-Popup.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabSummary-Popup" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-Popup-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-Popup-1024x640.png" /></a>
<a href='http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/tabsummary/'><img width="150" height="150" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-150x150.png" class="attachment-thumbnail" alt="TabSummary" data-attachment-id="5063" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary.png" data-orig-size="1280,800" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TabSummary" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-300x188.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/TabSummary-1024x640.png" /></a>

<p>Umm, wait, the images above look very similar with iOS rather than Android, particularly the <em>swipe-to-action</em> screens. Could it be possibly that I attach wrong images, you might asked. Nope! We&#8217;ve great surprises for you, Android fans! Stay tuned for my answer in the next post.</p>
<h1>Wrapping Up</h1>
<p>I hope this post may give you meaningful insights on better design for cross-platform, especially one that works for both tablets and phones. By streamlining the design and user flow at the beginning, jumping into development becomes much an easier task with clearer goal in mind.</p>
<blockquote><p>If you haven&#8217;t try out Crosslight, you can quickly jump start by requesting your free 30 day trial <a href="http://intersoftsolutions.com/RequestTrial">here</a>. You will be guided by our consultant team during your evaluation period.</p></blockquote>
<p>In the next post, we’ll see how can we use Crosslight to create this app and make it work across all platforms of different screen sizes and see how much code for this app can be optimized to work for multiple platforms.</p>
<h1>Update</h1>
<p>Read the <a href="http://blog.intersoftsolutions.com/2016/04/redesigning-xamarin-field-service-sample-with-crosslight-part-2/" target="_blank">part 2 here</a>, which contains highlights of the finished sample along with snippet codes and detailed explanations.</p>
<p>Till next post,<br />
Nicholas Lie</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/11/redesigning-xamarin-field-service-sample-with-crosslight/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iPad-Transition.mp4" length="569039" type="video/mp4" />
		</item>
		<item>
		<title>Adding Header and Footer for iOS TableView and Android ListView</title>
		<link>http://blog.intersoftsolutions.com/2015/11/adding-header-and-footer-for-ios-tableview-and-android-listview/</link>
		<comments>http://blog.intersoftsolutions.com/2015/11/adding-header-and-footer-for-ios-tableview-and-android-listview/#comments</comments>
		<pubDate>Wed, 18 Nov 2015 07:01:08 +0000</pubDate>
		<dc:creator><![CDATA[Nicholas Lie]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[kb-how-to-article]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[custom view]]></category>
		<category><![CDATA[footer]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[listview]]></category>
		<category><![CDATA[tableview]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=5159</guid>
		<description><![CDATA[Hi guys, I&#8217;m back with another blog post, this time covering how to use the a custom view for header and footer to be used alongside iOS TableView / Android TableView. You&#8217;ll see how you can easily create custom views and use them as headers and footers in [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-3.38.19-PM-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="Screen Shot 2015-11-19 at 3.38.19 PM" style="float:right; margin:0 0 10px 10px;" data-attachment-id="5164" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-3.38.19-PM.png" data-orig-size="1736,1334" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screen Shot 2015-11-19 at 3.38.19 PM" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-3.38.19-PM-300x231.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-3.38.19-PM-1024x787.png" /><p>Hi guys, I&#8217;m back with another blog post, this time covering how to use the a custom view for header and footer to be used alongside iOS TableView / Android TableView. You&#8217;ll see how you can easily create custom views and use them as headers and footers in your Crosslight apps.</p>
<p><img class="alignnone size-large wp-image-5164" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-3.38.19-PM-1024x787.png" alt="Screen Shot 2015-11-19 at 3.38.19 PM" width="604" height="464" /></p>
<p>After this project has completed, you&#8217;ll end up with a custom header and footer in your ListView/TableView. When you click on the Add Item button on the top, new item will be added to the list, and you can see how the header and footer is correctly persisted when the items collection is updated.</p>
<p>To complete this project, there are several steps need to be completed:</p>
<ul>
<li>Preparing the project</li>
<li>Creating custom views for iOS</li>
<li>Preparing the BIndingProvider</li>
<li>Preparing the ViewModel</li>
<li>Modify iOS ViewController and running the project</li>
<li>Creating custom views for Android</li>
<li>Modifying Android ListActivity and running the project</li>
</ul>
<p>Without further ado, let&#8217;s get started.</p>
<h1>Preparing the project</h1>
<p>For this sample, I&#8217;ll keep it nice and simple. This time, I&#8217;ll start from the Navigation template created using Crosslight Project Wizard. I&#8217;ll name this project: <strong>HeaderAndFooter</strong>.</p>
<h1>Creating custom views for iOS</h1>
<p>Let&#8217;s begin by creating a new custom header view for iOS, by right-clicking on the VIews folder in <strong>HeaderAndFooter.iOS/Views</strong> folder and choose <strong>Add</strong>, <strong>New File</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.57.27-PM.png"><img class="alignnone size-large wp-image-5166" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.57.27-PM-1024x285.png" alt="Screen Shot 2015-11-19 at 4.57.27 PM" width="604" height="168" /></a></p>
<p>Then choose <strong>Crosslight</strong>, <strong>Crosslight iOS View for iPhone</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.54.59-PM.png"><img class="alignnone size-large wp-image-5167" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.54.59-PM-1024x774.png" alt="Screen Shot 2015-11-19 at 4.54.59 PM" width="604" height="457" /></a></p>
<p>Give it a name of <strong>CustomHeader</strong>. This will generate two files, <em>CustomHeader.xib</em> and <em>CustomHeader.cs</em> for the designer files.</p>
<p>Then open the <em>CustomHeader.xib</em> using Xcode Interface Builder.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.59.08-PM.png"><img class="alignnone size-large wp-image-5168" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-4.59.08-PM-1024x174.png" alt="Screen Shot 2015-11-19 at 4.59.08 PM" width="604" height="103" /></a></p>
<p>In Xcode Interface Builder, drag a Label and a button.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.03.12-PM.png"><img class="alignnone size-large wp-image-5169" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.03.12-PM-1024x306.png" alt="Screen Shot 2015-11-19 at 5.03.12 PM" width="604" height="180" /></a></p>
<p>Set the label outlet as <strong>TxtHeader </strong>and the button as <strong>BtnHeader</strong>. I won&#8217;t go too much on the layouting details, but you can ensure the followings are set:</p>
<ul>
<li>Set the View size as Freeform, so you can adjust the view size freely.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.06.01-PM.png"><img class="alignnone  wp-image-5170" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.06.01-PM.png" alt="Screen Shot 2015-11-19 at 5.06.01 PM" width="321" height="89" /></a></li>
<li>Turn off Auto Layout.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.06.24-PM.png"><img class="alignnone  wp-image-5171" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.06.24-PM.png" alt="Screen Shot 2015-11-19 at 5.06.24 PM" width="318" height="183" /></a></li>
<li>Ensure that the View background is set to <strong>Default</strong> (no fill), this will avoid clipping issues when placed as the header view.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.07.15-PM.png"><img class="alignnone  wp-image-5172" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-5.07.15-PM.png" alt="Screen Shot 2015-11-19 at 5.07.15 PM" width="317" height="252" /></a></li>
</ul>
<p>Your custom header is now ready. Let&#8217;s move on to custom footer.</p>
<p>Basically, you&#8217;re going to perform the same tasks as adding a custom header, but the difference is that you&#8217;re going to give it a file name of <strong>CustomFooter</strong>, then provide a label with the outlet of <strong>TxtCopyright</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.14.16-PM.png"><img class="alignnone size-large wp-image-5174" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.14.16-PM-1024x222.png" alt="Screen Shot 2015-11-19 at 9.14.16 PM" width="604" height="131" /></a></p>
<h1>Preparing the BindingProvider</h1>
<p>Since you&#8217;ve successfully created the custom views, let&#8217;s prepare the <strong>BindingProvider</strong> first to prepare the properties and commands you wish to bind to the View. Open up <strong>NavigationBindingProvider</strong> (I renamed this file to MainBindingProvider to avoid confusion) and add the highlighted lines.</p><pre class="crayon-plain-tag">using Intersoft.Crosslight;

namespace HeaderAndFooter
{
    public class MainBindingProvider : BindingProvider
    {
        #region Constructors

        public MainBindingProvider()
        {
            ItemBindingDescription itemBinding = new ItemBindingDescription()
            {
                DisplayMemberPath = "Title",
                NavigateMemberPath = "Target"
            };

            this.AddBinding("TableView", BindableProperties.ItemsSourceProperty, "Items");
            this.AddBinding("TableView", BindableProperties.ItemTemplateBindingProperty, itemBinding, true);
            this.AddBinding("TableView", BindableProperties.SelectedItemProperty, "SelectedItem", BindingMode.TwoWay);
            
            this.AddBinding("BtnHeader", BindableProperties.TextProperty, "ButtonText");
            this.AddBinding("BtnHeader", BindableProperties.CommandProperty, "AddCommand");
            this.AddBinding("TxtCopyright", BindableProperties.TextProperty, "CopyrightText");
            this.AddBinding("TxtHeader", BindableProperties.TextProperty, "HeaderText");
        }

        #endregion
    }
}</pre><p>From the added lines, notice that we&#8217;re going to do the following:</p>
<ul>
<li>Bind <strong>ButtonText</strong> property in the ViewModel to the <strong>BtnHeader</strong> button.</li>
<li>Bind the ViewModel&#8217;s built-in <strong>AddCommand</strong> to the <strong>BtnHeader</strong> button. This is available in the <em>EditableListViewModel</em> shipped in Crosslight.</li>
<li>Bind the <strong>HeaderText</strong> property in the ViewModel to the <strong>TxtHeader</strong> label.</li>
<li>Bind the <strong>CopyrightText</strong> property in the ViewModel to <strong>TxtCopyright</strong> label. This is for the footer.</li>
</ul>
<p>Since you&#8217;ve prepared everything in the BindingProvider, let&#8217;s modify the ViewModel.</p>
<h1>Modifying the ViewModel</h1>
<p>The  <strong>NavigationViewModel </strong>now looks like the following. It&#8217;s located inside the <strong>HeaderAndFooter.Core/ViewModels</strong> folder.</p><pre class="crayon-plain-tag">using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using Intersoft.Crosslight;

namespace HeaderAndFooter.ViewModels
{
    public class NavigationViewModel : SampleListViewModelBase&lt;NavigationItem&gt;
    {
        #region Constructors

        public NavigationViewModel()
        {
            ObservableCollection&lt;NavigationItem&gt; items = new ObservableCollection&lt;NavigationItem&gt;();

            items.Add(new NavigationItem("Simple Page", "About", typeof(SimpleViewModel)));
            items.Add(new NavigationItem("About This App", "About", typeof(AboutNavigationViewModel)));

            this.SourceItems = items;

            this.ButtonText = "Add Item";
            this.CopyrightText = "Copyright © Intersoft Solutions";
        }

        #endregion

        #region Properties

        private string _aboutText { get; set; }
        private string _buttonText { get; set; }
        private string _copyrightText { get; set; }
        private string _headerText { get; set; }

        public string AboutText
        {
            get { return _aboutText; }
            set
            {
                if (_aboutText != value)
                {
                    _aboutText = value;
                    OnPropertyChanged("AboutText");
                }
            }
        }

        public string ButtonText
        {
            get { return _buttonText; }
            set
            {
                if (_buttonText != value)
                {
                    _buttonText = value;
                    OnPropertyChanged("ButtonText");
                }
            }
        }

        public string CopyrightText
        {
            get { return _copyrightText; }
            set
            {
                if (_copyrightText != value)
                {
                    _copyrightText = value;
                    OnPropertyChanged("CopyrightText");
                }
            }
        }

        public string HeaderText
        {
            get
            {
                _headerText = this.Items.Count() + " items.";
                return _headerText;
            }
            set
            {
                if (_headerText != value)
                {
                    _headerText = value;
                    OnPropertyChanged("HeaderText");
                }
            }
        }

        #endregion

        #region Methods

        protected override bool CanExecuteAdd(object parameter)
        {
            return true;
        }

        protected override void ExecuteAdd(object parameter)
        {
            base.ExecuteAdd(parameter);

            NavigationItem newItem = new NavigationItem("Simple Page", "About", typeof(SimpleViewModel));
            var items = this.SourceItems.ToObservable();
            items.Add(newItem);
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            this.OnPropertyChanged("HeaderText");
        }

        #endregion
    }
}</pre><p>Let&#8217;s take a deeper look at this class, starting from the top. In the constructor, we&#8217;ve prepared our <strong>SourceItems</strong> with <strong>ObservableCollection</strong>. We then initialize the <strong>ButtonText</strong> property and the <strong>CopyrightText</strong> property. The <strong>ButtonText</strong> and <strong>CopyrightText</strong> property are all MVVM-ready properties. The <strong>HeaderText</strong> is also an MVVM-ready property, but in the property getter, the text is always updated according to the number of items which exists in the list.</p>
<p>Right after the properties, we then override the built-in <strong>CanExecuteAdd</strong> method to return true so that the AddCommand can be executed, as well as overriding the actions for the <strong>ExecuteAdd </strong>method. Here, we simply add a new <strong>NavigationItem</strong> to the list. Just right after the method, Crosslight has provided an elegant way to perform any additional changes to other properties or any other implementation by overriding the <strong>OnCollectionChanged</strong> method. In the method, we trigger the <strong>OnPropertyChanged</strong> of the <strong>HeaderText</strong>, so that the number of items is always updated in our custom header.</p>
<h1>Modify iOS ViewController and running the project</h1>
<p>Now that you got the Core project covered, let&#8217;s modify the <strong>MainViewController</strong> (located inside <strong>HeaderAndFooter.iOS/ViewControllers</strong>) a bit.</p><pre class="crayon-plain-tag">using CoreGraphics;
using Foundation;
using HeaderAndFooter.ViewModels;
using Intersoft.Crosslight;
using Intersoft.Crosslight.iOS;
using UIKit;

namespace HeaderAndFooter.iOS.ViewControllers
{
    [Register("MainViewController")]
    [ImportBinding(typeof(MainBindingProvider))]
    public class MainViewController : UITableViewController&lt;NavigationViewModel&gt;
    {
        #region Properties

        public override UIViewTemplate HeaderViewTemplate
        {
            get { return new UIViewTemplate(CustomHeader.Nib); }
        }

        public override UIViewTemplate FooterViewTemplate
        {
            get { return new UIViewTemplate(CustomFooter.Nib); }
        }

        public override TableViewInteraction InteractionMode
        {
            get { return TableViewInteraction.Navigation; }
        }

        public override bool ShowGroupHeader
        {
            get { return false; }
        }

        public override UITableViewStyle TableViewStyle
        {
			get { return UITableViewStyle.Plain; }
        }

        #endregion

        #region Methods

        protected override void InitializeView()
        {
            base.InitializeView();

            // set navigation title
            this.NavigationItem.Title = "Crosslight App";
        }

        #endregion
    }
}</pre><p>In the <strong>MainViewController</strong>, we&#8217;ve overridden the <strong>HeaderViewTemplate</strong> as well as <strong>FooterViewTemplate</strong> to return the Nib for each custom header and footer view that we&#8217;ve just defined. We also made things simpler by not showing the group header as wellas ensuring that the used <strong>TableViewStyle</strong> is <strong>Plain</strong>. Run the project. You should get the following result.</p>
<div style="width: 500px; " class="wp-video"><video class="wp-video-shortcode" id="video-5159-8" width="500" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS-header-footer.mp4?_=8" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS-header-footer.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS-header-footer.mp4</a></video></div>
<p>If you&#8217;re curious about the separator that exists between the header with the table view, as well as the footer with the table view, it&#8217;s because I&#8217;ve added an additional view in the custom header and footer layout, with the height of 1 unit and giving it a light gray background, to show the boundaries of the custom header and custom footer view. We&#8217;re going to do the same with Android layout later. You&#8217;ve completed the iOS version. Let&#8217;s move on to the Android.</p>
<h1>Creating custom views for Android</h1>
<p>Similar to iOS, you&#8217;ll need to create a custom header view first for Android. To do this, simply right click on the <strong>Resources/layout</strong> folder in the <strong>HeaderAndFooter.Android/Views</strong> folder, then choose <strong>Add</strong>, <strong>New Item</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.42.51-PM.png"><img class="alignnone size-large wp-image-5177" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.42.51-PM-1024x202.png" alt="Screen Shot 2015-11-19 at 9.42.51 PM" width="604" height="119" /></a></p>
<p>&nbsp;</p>
<p>From the dialog that appears, choose <strong>Android</strong>, <strong>Layout</strong>, and give it a name of <strong>CustomHeader</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.43.39-PM.png"><img class="alignnone size-large wp-image-5178" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-19-at-9.43.39-PM-1024x794.png" alt="Screen Shot 2015-11-19 at 9.43.39 PM" width="604" height="468" /></a></p>
<p>&nbsp;</p>
<p>And here&#8217;s the contents of the <strong>CustomHeader.axml</strong> file.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    &gt;
    &lt;LinearLayout 
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        &gt;
        &lt;TextView
        	android:id="@+id/TxtHeader"
        	android:layout_width="fill_parent"
        	android:layout_height="30dp"
        	android:textSize="20sp"
        	android:gravity="left"
            android:layout_weight="1"
        /&gt;
        &lt;Button 
            android:id="@+id/BtnHeader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        /&gt;
    &lt;/LinearLayout&gt;
    &lt;LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="1px"
            android:background="#f2f2f2"
        /&gt;
&lt;/LinearLayout&gt;</pre><p>This layout simply contains a pretty much similar layout with iOS, that contains a label, a button, and a gray separator at the bottom. Repeat the same procedure for the custom footer layout. Here&#8217;s the contents of the <strong>CustomFooter.axml</strong> file.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    &gt;
    &lt;LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="1px"
        android:background="#f2f2f2"
    /&gt;
    &lt;TextView
    	android:id="@+id/TxtCopyright"
    	android:layout_width="fill_parent"
    	android:layout_height="30dp"
    	android:textSize="12sp"
    	android:gravity="center"
        android:fontFamily="sans-serif-light" 
    /&gt;
&lt;/LinearLayout&gt;</pre><p></p>
<h1></h1>
<h1>Modifying Android ListActivity and running the project</h1>
<p>Since you&#8217;ve prepared the custom views let&#8217;s modify the Android ListActivity to display our custom header and footer. Open up <strong>MainActivity </strong>in the <strong>HeaderAndFooter.Android/Activities</strong> folder and take note of the following changes.</p><pre class="crayon-plain-tag">using Android.App;
using HeaderAndFooter.ViewModels;
using Intersoft.Crosslight;
using Intersoft.Crosslight.Android;

namespace HeaderAndFooter.Android
{
    [Activity(Label = "Crosslight App", Icon = "@drawable/icon")]
    [ImportBinding(typeof(MainBindingProvider))]
    public class MainActivity : ListActivity&lt;NavigationViewModel&gt;
    {
        #region Methods

        protected override void InitializeView()
        {
            base.InitializeView();

            this.RegisterViewIdentifier("TableView", this.ListView);
        }

        #endregion

        #region Properties

        protected override int ContentLayoutId
        {
            get { return Intersoft.Crosslight.Android.Resource.Layout.listgroupsectionlayout; }
        }

        protected override int FooterLayoutId
        {
            get { return Resource.Layout.CustomFooter; }
        }

        protected override int HeaderLayoutId
        {
            get { return Resource.Layout.CustomHeader; }
        }

        public override ListViewInteraction InteractionMode
        {
            get { return ListViewInteraction.Navigation; }
        }

        #endregion
    }
}</pre><p>All you need to do is just override the <strong>FooterLayoutId</strong> as well <strong>HeaderLayoutId</strong> and provide the layout you&#8217;ve just created. If you notice in the template, right in the InitializeView method, we&#8217;re registering the ListView with the TableView identifier at runtime. This is how you would register a view at runtime. For more information in registering view at runtime, check out <a href="http://developer.intersoftsolutions.com/display/crosslight/Getting+Started+with+Crosslight+Android+App#GettingStartedwithCrosslightAndroidApp-RegisteringaViewIdentifieratRuntime">this document</a> in the Developer Center.</p>
<p>You&#8217;re now ready to run the project. You should get the result similar to the following.</p>
<div style="width: 500px; " class="wp-video"><video class="wp-video-shortcode" id="video-5159-9" width="500" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android-header-footer.mp4?_=9" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android-header-footer.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android-header-footer.mp4</a></video></div>
<h1>Wrapping Up</h1>
<p>You&#8217;ve seen how easy it is to set up a custom header and footer view to use with iOS TableView and Android ListView. With Crosslight, the custom views are automatically compatible with data binding and Crosslight takes care of the magic, so you can focus on building your app instead of having to worry about wiring behind the scenes. Hopefully this gives you a good insight on how Crosslight accomplishes business scenarios elegantly, without compromising any of the MVVM-design pattern enforced throughout the app.</p>
<p>As always, you can find the source code to this post here: <a href="http://git.intersoftsolutions.com/projects/CT/repos/crosslightheaderandfooter/browse">http://git.intersoftsolutions.com/projects/CT/repos/crosslightheaderandfooter/browse.</a></p>
<p>See you in the next post,<br />
Nicholas Lie</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/11/adding-header-and-footer-for-ios-tableview-and-android-listview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS-header-footer.mp4" length="535560" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android-header-footer.mp4" length="319873" type="video/mp4" />
		</item>
		<item>
		<title>Extending Crosslight Form Builder</title>
		<link>http://blog.intersoftsolutions.com/2015/11/extending-crosslight-form-builder-2/</link>
		<comments>http://blog.intersoftsolutions.com/2015/11/extending-crosslight-form-builder-2/#comments</comments>
		<pubDate>Tue, 17 Nov 2015 07:00:18 +0000</pubDate>
		<dc:creator><![CDATA[Nicholas Lie]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Reference Samples]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Cross Platform]]></category>
		<category><![CDATA[form builder]]></category>
		<category><![CDATA[general]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=5101</guid>
		<description><![CDATA[Since you’ve managed to get started with Crosslight Form Builder, let’s move on a bit to see how we can extend the capabilities of the Crosslight Form Builder beyond its original capabilities. In this post we’re going to learn how to add an option to [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="Untitled.001" style="float:right; margin:0 0 10px 10px;" data-attachment-id="5108" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001.png" data-orig-size="1024,768" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Untitled.001" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001-300x225.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001-1024x768.png" /><p>Since you’ve managed to <a href="http://blog.intersoftsolutions.com/2015/11/getting-started-with-crosslight-form-builder/">get started with Crosslight Form Builder</a>, let’s move on a bit to see how we can extend the capabilities of the Crosslight Form Builder beyond its original capabilities. In this post we’re going to learn how to add an option to choose the driver in <a href="http://git.intersoftsolutions.com/projects/CT/repos/crosslightformbuilder/browse">CrosslightFormBuilder sample</a>, as well as showing a custom view with the driver’s photo in the form, with the driver&#8217;s phone number, which when tapped, will initiate a call to the driver.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001.png"><img class="alignnone size-large wp-image-5108" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Untitled.001-1024x768.png" alt="Untitled.001" width="604" height="453" /></a></p>
<p>&nbsp;</p>
<p>There are two major enhancements to be done:</p>
<ul>
<li>Providing driver selection</li>
<li>Providing custom driver view</li>
</ul>
<h1>Providing Driver Selection</h1>
<p>Let&#8217;s try to create the <strong>Driver</strong> selection. At a quick overview, here&#8217;s a list of subtasks to be done in order to achieve this functionality:</p>
<ul>
<li>Prepare the <strong>Driver</strong> model</li>
<li>Prepare the <strong>Driver Repository</strong> that populates the list of drivers.</li>
<li>Prepare the <strong>DriverListViewModel </strong>that populates the items from the repository.</li>
<li>Update the <strong>Form Metadata </strong>and connect the <strong>DriverListViewModel</strong>.</li>
</ul>
<p>Let&#8217;s go through each one, step-by-step.</p>
<h2>Prepare the Driver model</h2>
<p>To create the <strong>Driver</strong> model, let&#8217;s create a new file named <em>Driver.cs</em> under <strong>CrosslightFormBuilder.Core/Models</strong> folder. The contents are as follows.</p><pre class="crayon-plain-tag">#region Usings

using CrosslightFormBuilder.Models;

#endregion

namespace CrosslightFormBuilder.Core.Models
{
    public class Driver : ModelBase
    {
        #region Constructors

        public Driver(int id, string name, string phone, byte[] image)
        {
            this.Id = id;
            this.Name = name;
            this.Phone = phone;
            this.Image = image;
        }

        #endregion

        #region Fields

        private int _id;
        private byte[] _image;
        private string _name;
        private string _phone;

        #endregion

        #region Properties

        public int Id
        {
            get { return _id; }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        public byte[] Image
        {
            get { return _image; }
            set
            {
                if (_image != value)
                {
                    _image = value;
                    OnPropertyChanged("Image");
                }
            }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public string Phone
        {
            get { return _phone; }
            set
            {
                if (_phone != value)
                {
                    _phone = value;
                    OnPropertyChanged("Phone");
                }
            }
        }

        #endregion
    }
}</pre><p>The Driver model contain 4 MVVM-ready properties: <strong>ID</strong> (<em>int</em>), <strong>Image</strong> (<em>byte[]</em>), <strong>Name </strong>(<em>string</em>), and <strong>Phone</strong> (<em>string</em>). That&#8217;s basically it. I&#8217;ve also prepared a constructor for quick and easy initialization. Now your Driver model is ready. Let&#8217;s move on.</p>
<h2>Prepare the Driver Repository</h2>
<p>Upon reading the heading, you might have two questions: What is this repository thingy and why do I need it? The repository pattern is more of a best-practice design pattern that handles the actual data processing for your applications. A data repository for your app.</p>
<p>For example, right now your app might currently retrieve data by performing queries to a database server, then one day you decided to change the data retrieval process. Rather than making changes to each and every <em>ViewModel</em>, you can do so by just replacing the data repository. No changes in ViewModel needed. To learn more about the Repository Pattern, check out our Developer Center documentation <a href="http://developer.intersoftsolutions.com/display/crosslight/Repository+Pattern">here</a>.</p>
<p>So, let&#8217;s get started in creating our <strong>Driver repository</strong>. First thing you need to do is define the interfaces needed for the repository. Create a new interface in <em>CrosslightFormBuilder.Core/ModelServices</em>, named <strong>IDataRepository.cs</strong>, also creating the folder as necessary. The contents of the file are as follows.</p><pre class="crayon-plain-tag">public interface IDataRepository&lt;TEntity, in TKey&gt; where TEntity : class
{
    #region Methods

    TEntity Get(TKey id);
    IEnumerable&lt;TEntity&gt; GetAll();

    #endregion
}</pre><p>We&#8217;ll prepare an interface to get the <em>Driver</em> entity based on the given ID. Notice that everything is defined as generic here. Also another interface to return all entities when calling <em>GetAll()</em> method.</p>
<p>Proceed by creating the interface for the <em>Driver</em> repository in <em>CrosslightFormBuilder.Core/ModelServices </em>folder, named <strong>IDriverRepository.cs</strong>, also creating the folder as necessary.</p><pre class="crayon-plain-tag">public interface IDriverRepository : IDataRepository&lt;Driver, int&gt;
{
    #region Methods

    Driver GetByName(string name);

    #endregion
}</pre><p>There&#8217;s nothing much to see here, we simply added a new method to get the <em>Driver</em> entity by the driver&#8217;s <em>Name </em>by subclassing the previously created <em>IDataRepository</em> interface. Let&#8217;s move on by creating the concrete <em>DriverRepository</em> implementation. Create a new file called <strong>DriverRepository.cs </strong>inside <em>CrosslightFormBuilder.Core/ModelServices</em> folder.</p><pre class="crayon-plain-tag">public class DriverRepository : IDriverRepository
{
    #region Properties

    public List&lt;Driver&gt; _items { get; set; }

    #endregion

    #region Methods

    public Driver Get(int id)
    {
        return this.GetAll().FirstOrDefault(o =&gt; o.Id == id);
    }

    public IEnumerable&lt;Driver&gt; GetAll()
    {
        if (_items == null)
        {
            _items = new List&lt;Driver&gt;();
            _items.Add(new Driver(1, "John", "+123456", this.GetType().Assembly.GetManifestResourceStream("CrosslightFormBuilder.Core.Assets.john.png").ToByte()));
            _items.Add(new Driver(2, "Brad", "+134567", this.GetType().Assembly.GetManifestResourceStream("CrosslightFormBuilder.Core.Assets.brad.png").ToByte()));
            _items.Add(new Driver(2, "Charles", "+145678", this.GetType().Assembly.GetManifestResourceStream("CrosslightFormBuilder.Core.Assets.charles.png").ToByte()));
        }

        return _items;
    }

    public Driver GetByName(string name)
    {
        return this.GetAll().FirstOrDefault(o =&gt; o.Name == name);
    }

    #endregion
}</pre><p>Here, you can then provide the real implementation to retrieve the list of drivers, also getting the drivers by name and ID. The highlighted line shows how the list of <em>Drivers</em> are populated, by utilizing the constructor we&#8217;ve provided for our <em>Driver</em> model earlier. Also notice that we&#8217;ve provided the image to be used for each driver. Oh yeah, before we forget, let&#8217;s go ahead and use these images for the drivers and put it inside the <strong>CrosslightFormBuilder.Core/Assets</strong> folder, also creating the folder as needed.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/brad.png"><img class=" size-full wp-image-5118 alignleft" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/brad.png" alt="brad" width="200" height="200" /></a>  <a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/charles.png"><img class=" size-large wp-image-5119 alignleft" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/charles.png" alt="charles" width="200" height="200" /></a>  <a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/john.png"><img class=" size-large wp-image-5120 alignleft" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/john.png" alt="john" width="200" height="200" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Make sure that these images&#8217; <em>BuildAction</em> is set to <em>EmbeddedResource</em> so that they can be used in your application. Also, if you try to build the project now, you might get an error on the <em>ToByte()</em> method. To fix this, create a new file that contains an extension method to convert a <em>Stream</em> to array of bytes. Create a file named <em>StreamExtensions.cs, </em>and put it inside the <strong>CrosslightFormBuilder.Core/Extensions</strong> folder.</p><pre class="crayon-plain-tag">public static class StreamExtensions
{
    #region Methods

    public static byte[] ToByte(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }

    #endregion
}</pre><p>A handy tip for you: these extension method provides an easy way to extend the functionalities of a certain class, that is reusable within your application. For example, if you wish to create an extension, for let&#8217;s say, converting a <em>string </em>to a <em>byte[]</em>, you can definitely do something similar to this.</p>
<p>Now that you&#8217;ve the got the repository part ready, let&#8217;s hook it up to the <em>ViewModel</em>.</p>
<h2>Prepare the DriverListViewModel</h2>
<p>Start by creating a new ViewModel file called <strong>DriverListViewModel.cs</strong> and put it inside <strong>CrosslightFormBuilder.Core/ViewModels</strong> folder. Here&#8217;s the contents of the file.</p><pre class="crayon-plain-tag">public class DriverListViewModel : ListViewModelBase&lt;Driver&gt;
{
    #region Constructors

    public DriverListViewModel()
    {
        this.SourceItems = this.Repository.GetAll().ToObservable();
    }

    #endregion

    #region Properties

    private IDriverRepository Repository
    {
        get
        {
            if (Container.Current.CanResolve&lt;IDriverRepository&gt;())
                return Container.Current.Resolve&lt;IDriverRepository&gt;();
            return new DriverRepository();
        }
    }

    #endregion
}</pre><p>Here, we populate the <em>SourceItems</em> when the <strong>DriverListViewModel</strong> is constructed, just by calling the previously created <em>GetAll()</em> method from our interface. Also notice that we&#8217;ve provided the <em>Repository</em> property which is resolved upon the property&#8217;s getter. This is also called as <em>IoC</em> (Inversion of Control). To use the <em>IoC</em> pattern, you&#8217;ll need to register the previously created <em>DriverRepository</em> to be used globally in the application. To do this, open up the <strong>AppService.cs</strong> file in the <em>CrosslightFormBuilder.Core/Infrastructure</em> folder and add this line in the constructor.</p><pre class="crayon-plain-tag">public CrosslightAppAppService(IApplicationContext context) : base(context)
{
    Container.Current.Register&lt;IDriverRepository, DriverRepository&gt;().WithLifetimeManager(new ContainerLifetime());
}</pre><p>Your <em>ViewModel</em> is now ready to be used to populate the list of <em>Drivers</em>.</p>
<h2>Update the FormMetadata</h2>
<p>Since you already have the list of drivers properly populated from the DriverListViewModel, we&#8217;ll need to modify the <strong>OrderFormMetadata</strong> a bit. From the initial <strong>OrderFormMetadata </strong>class in the <em>Order.cs </em>file, let&#8217;s modify the <strong>TaxiChoiceSection</strong> class to include the driver selection.</p><pre class="crayon-plain-tag">public class TaxiChoiceSection
{
    #region Fields

    [Display(Caption = "Car Type")]
    [Editor(EditorType.AutoDetect)]
    [Layout(Style = LayoutStyle.RightDetail)]
    public CarType CarType;

    [Editor(EditorType.Selection)]
    [SelectedItemBinding(Path = "Driver")]
    [Binding(Path = "Driver.Name")]
    [SelectionInput(SelectionMode.Single, DisplayMemberPath = "Name", ListSourceType = typeof(DriverListViewModel))]
    public Driver Driver;

    [Display(Caption = "Airport?")]
    [Editor(EditorType.Switch)]
    [Layout(Style = LayoutStyle.RightDetail)]
    public bool IsAirport;

    #endregion
}</pre><p>The highlighted lines above shows the added definition for the driver selection. Let&#8217;s inspect this line by line.</p>
<ul>
<li><em>[Editor(EditorType.Selection)]</em><br />
This determines which editor type to be used.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/selection.002.png"><img class="alignnone size-large wp-image-5122" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/selection.002-1024x768.png" alt="selection.002" width="604" height="453" /></a></li>
<li><em>[SelectedItemBinding(Path = &#8220;Driver&#8221;)]</em><br />
This attribute determines which binding path for the selected item used in the Form Builder. In this case, the item for the Form Builder is of type <strong>Order</strong>, which has the <strong>Driver</strong> property. That&#8217;s where we&#8217;re going to bind our selection into. (<strong>OrderViewModel.Item.Driver</strong>)</li>
<li><em>[Binding(Path = &#8220;Driver.Name&#8221;)]</em><br />
The <strong>BindingAttribute</strong> determines which property of the <strong>Driver</strong> model that is going to be displayed in the form after selection has completed.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/binding.png"><img class="alignnone size-full wp-image-5123" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/binding.png" alt="binding" width="491" height="232" /></a></li>
<li><em>[SelectionInput(SelectionMode.Single, DisplayMemberPath = &#8220;Name&#8221;, ListSourceType = typeof(DriverListViewModel))]</em><strong><br />
</strong>The <strong>SelectionInputAttribute </strong>determines the selection editor behavior, which <em>ViewModel</em> provides the items source for the list, as well as the property to be displayed on the list of selection, or also often known as <strong>DisplayMemberPath</strong>.<br />
<a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/selection-editor.png"><img class="alignnone size-full wp-image-5124" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/selection-editor.png" alt="selection editor" width="476" height="192" /></a></li>
</ul>
<p>By now, you&#8217;ve successfully provided a driver selection for the Form Builder. How about adding the custom view on the bottom of the form?</p>
<h1>Providing Custom Driver View</h1>
<p>After the user has selected the driver, it&#8217;s best for us to show the driver that the user has selected by providing a custom view at the bottom of the form. Let&#8217;s learn how you can use a custom view resource to be used along with the Form Builder, complete with data binding capabilities. In overall, there are several steps needed to achieve this:</p>
<ul>
<li>Provide the custom driver view for iOS</li>
<li>Update the Form Metadata</li>
<li>Provide the Binding Provider</li>
<li>Bind to ViewModel</li>
<li>Provide the custom driver view for Android</li>
</ul>
<p>Let&#8217;s go through each step, one-by-one.</p>
<h2>Provide the Custom Driver View for iOS</h2>
<p>To provide the custom driver view for iOS, all you need to do is creating a new Crosslight view for iPhone. To do this, you can utilize the item template shipped with Crosslight. In your iOS project, in the <em>Views</em> folder, right-click and add a new file. Under <strong>Crosslight</strong>, choose <strong>Crosslight iOS View for iPhone</strong>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-13-at-6.27.32-PM.png"><img class="alignnone size-large wp-image-5125" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-13-at-6.27.32-PM-1024x669.png" alt="Screen Shot 2015-11-13 at 6.27.32 PM" width="604" height="395" /></a></p>
<p>Let&#8217;s give it a name of <strong>CallDriverButton</strong>. What this will do is Crosslight will create two files, namely <strong>CallDriverButton.xib</strong> and <strong>CallDriverButton.cs</strong>. All you need to do is create a new layout by opening the <strong>CallDriverButton.xib</strong> in <em>Xcode Interface Builder</em>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/xcode-interface-builder.png"><img class="alignnone size-large wp-image-5126" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/xcode-interface-builder-1024x282.png" alt="xcode-interface-builder" width="604" height="166" /></a></p>
<p>Create your layout any way you want it. Just create an <em>ImageView</em>, a <em>Label</em>, and a <em>Button</em>.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/outlet1.png"><img class="alignnone size-full wp-image-5128" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/outlet1.png" alt="outlet" width="1021" height="449" /></a></p>
<p>Set the outlet for each.</p>
<ul>
<li><strong>ImageView</strong>: DriverImage</li>
<li><strong>Label</strong>: DriverName</li>
<li><strong>Button</strong>: CallButton</li>
</ul>
<p>I know, my layout looks awful. But all I really want to show you is how you can inject your own custom views into the form using the Form Builder. So, after your layout&#8217;s done, save it and go back to Xamarin Studio.</p>
<h2>Update the Form Metadata</h2>
<p>Now that your layout is done, let&#8217;s update our <strong>OrderFormMetadata</strong> a bit to include this new view in our form layout. Open up <strong>Order.cs</strong>, and let&#8217;s create a new section and call it <strong>CallDriverSection</strong>, or anything you want.</p><pre class="crayon-plain-tag">public class CallDriverSection
{
    [Editor(EditorType.Custom, CustomEditorIdentifier = "CallDriverButton")]
    public object CallDriver;
}</pre><p>Now I&#8217;d like you to pay attention how easy it is to embed a custom view into a Crosslight Form. From the definition above, you can see that we simply set the editor type to custom, then set the <strong>CustomEditorIdentifier</strong> set to <strong>CallDriverButton</strong>. In iOS, this corresponds to the name of the XIB that we&#8217;ve defined for our custom view. While on Android, this also corresponds to the name of the Android Layout file we&#8217;ve defined for our custom view layout. Simple as that.</p>
<blockquote><p>We&#8217;ve made it super easy for developers to create a beautiful platform-specific data form by combining robust pre-built editors for common input and flexible custom views for more complex user interface. This allows you to mix and match what works best for you, and let Crosslight do the magic at runtime.</p></blockquote>
<p>After you&#8217;ve created this section, let&#8217;s add this at the bottom of our form.</p><pre class="crayon-plain-tag">[Form(Title = "Order Form")]
public class OrderFormMetadata
{
    #region Fields

    [Section(Header = "Passenger Details")]
    public PassengerDetailsSection PassengerDetails;

    [Section(Header = "Taxi Choice")]
    public TaxiChoiceSection TaxiChoiceSection;

    [Section]
    public CallDriverSection CallDriverSection;

    #endregion
}</pre><p>You&#8217;re done with the form metadata. But there&#8217;s something missing. What about those outlets we&#8217;ve defined earlier? How can we bind data to it?</p>
<h2>Provide the Binding Provider</h2>
<p>Simple. It&#8217;s basically the way you would do any data binding with Crosslight. Yes, you should provide a <strong>BindingProvider</strong> for the form. In addition to automatic bindings, Form Builder also supports natural data binding process through the use of <strong>BindingProvider</strong>. In this case, let&#8217;s create a new <strong>BindingProvider</strong> called <strong>OrderBindingProvider.cs</strong>. Let&#8217;s put this under <strong>CrosslightFormBuilder.Core/BindingProviders</strong> folder. The contents of the <strong>OrderBindingProvider</strong> are as follows.</p><pre class="crayon-plain-tag">public class OrderBindingProvider : BindingProvider
{
    #region Constructors

    public OrderBindingProvider()
    {
        this.AddBinding("DriverImage", BindableProperties.ImageProperty, "Item.Driver.Image");
        this.AddBinding("DriverName", BindableProperties.TextProperty, "Item.Driver.Name");
        this.AddBinding("CallButton", BindableProperties.TextProperty, "Item.Driver.Phone");
        this.AddBinding("CallButton", BindableProperties.CommandProperty, "CallCommand");
    }

    #endregion
}</pre><p>Here, we&#8217;ve simply used the outlets we&#8217;ve defined earlier and bind them automatically to the selected Driver in the form. We&#8217;ve also added a binding from the <strong>CallButton</strong> to the <strong>CallCommand</strong> in the ViewModel, which can be used to call the driver immediately upon click. And don&#8217;t forget to use the newly created <strong>OrderBindingProvider</strong> in your <strong>OrderViewController</strong>.</p>
<blockquote><p>Again, Crosslight does a lot of magic behind the scene which enables you to define data binding in such a simple definition. Looking back, we just need to create a view, define the outlets, and provide the bindings. Crosslight takes care the connection between all those layers at runtime.</p></blockquote>
<p></p><pre class="crayon-plain-tag">[Register("OrderViewController")]
[ImportBinding(typeof(OrderBindingProvider))]
public class OrderViewController : UIFormViewController&lt;OrderViewModel&gt;
{
    ...
}</pre><p></p>
<h2>Bind to ViewModel</h2>
<p>Afterwards, in the <strong>OrderViewModel</strong>, we simply add a new DelegateCommand for the phone number.</p><pre class="crayon-plain-tag">public class OrderViewModel : EditorViewModelBase&lt;Order&gt;
{
    #region Properties

    /// &lt;summary&gt;
    /// Gets the type of the form metadata associated to the editor.
    /// &lt;/summary&gt;
    /// &lt;value&gt;
    /// The type of the form metadata.
    /// &lt;/value&gt;
    public override Type FormMetadataType
    {
        get { return typeof(OrderFormMetadata); }
    }
    
    public DelegateCommand CallCommand { get; set; }

    #endregion
    
    #region Constructors
    
    public OrderViewModel()
    {
        this.CallCommand = new DelegateCommand(ExecuteCall);
    }
    
    #endregion

    #region Methods
    
    private void ExecuteCall(object obj)
    {
        this.MobileService.Telephony.Call(this.Item.Driver.Phone);
    }

    /// &lt;summary&gt;
    /// Executes the save command.
    /// &lt;/summary&gt;
    /// &lt;param name="parameter"&gt;Parameter.&lt;/param&gt;
    protected override void ExecuteSave(object parameter)
    {
        this.Validate();

        if (!this.HasErrors)
        {
            StringBuilder passengerDetails = new StringBuilder();
            passengerDetails.Append("Name: " + this.Item.Name + "\n");
            passengerDetails.Append("Pickup Time: " + this.Item.PickupTime + "\n");
            passengerDetails.Append("Going to the airport? " + this.Item.IsAirport + "\n");
            passengerDetails.Append("Car Type: " + this.Item.CarType + "\n");
            passengerDetails.Append("Driver: " + this.Item.Driver.Name);

            this.MessagePresenter.Show(passengerDetails.ToString(), "Confirm Order", new[] {"Yes", "No"}, selection =&gt;
            {
                if (selection == 0) //Yes
                {
                    this.ToastPresenter.Show("Your order has been placed.");
                }
                else
                {
                    this.ToastPresenter.Show("You cancelled the order.");
                }
            });
        }
        else
        {
            this.MessagePresenter.Show(this.ErrorMessage);
        }

    }
    

    /// &lt;summary&gt;
    /// Called when this instance is navigated.
    /// &lt;/summary&gt;
    /// &lt;param name="parameter"&gt;Parameter.&lt;/param&gt;
    public override void Navigated(NavigatedParameter parameter)
    {
        base.Navigated(parameter);

        this.Item = new Order();
        this.Item.PickupTime = DateTime.Now;
    }

    #endregion
}</pre><p>Everything seems pretty much the same, except for the additional <strong>CallCommand</strong> we&#8217;ve defined for the <strong>CallButton</strong>. Run the project and you should now see iOS version is now working properly. Try selecting a driver and that driver detail will be automatically shown in the custom view you&#8217;ve defined. When you run this on an iPhone, you can even immediately perform a phone call to the driver&#8217;s number directly.</p>
<div style="width: 400px; " class="wp-video"><video class="wp-video-shortcode" id="video-5101-10" width="400" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS.mp4?_=10" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS.mp4</a></video></div>
<p>&nbsp;</p>
<p>What about Android?</p>
<h2>Provide the Custom Driver View for Android</h2>
<p>This is where the Form Builder excels. Since you&#8217;ve completed the iOS version, all you need to do is just provide the custom layout and use the previously created <strong>OrderBindingProvider</strong>. Let&#8217;s take a look how to achieve this.</p>
<p>First, create a new Android Layout file by right clicking on the <strong>CrosslightFormBuilder.Android/Resources/layout</strong> folder. Then choose <strong>Add</strong>, <strong>New Item</strong>. Select <strong>Android, Layout</strong>. Remember to give it a name of <strong>CallDriverButton</strong>, as this corresponds to the <strong>CustomViewIdentifier</strong> defined in the FormMetadata earlier.</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-13-at-9.49.39-PM.png"><img class="alignnone size-large wp-image-5134" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-13-at-9.49.39-PM-1024x579.png" alt="Screen Shot 2015-11-13 at 9.49.39 PM" width="604" height="342" /></a></p>
<p>Provide the layout as follows.</p><pre class="crayon-plain-tag">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"&gt;
    &lt;LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"&gt;
        &lt;ImageView
            android:id="@+id/DriverImage"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center" /&gt;
        &lt;TextView
            android:id="@+id/DriverName"
            android:layout_width="wrap_content"
            android:layout_height="20sp"
            android:layout_gravity="center" /&gt;
        &lt;Button
            android:id="@+id/CallButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" /&gt;
    &lt;/LinearLayout&gt;
&lt;/RelativeLayout&gt;</pre><p>After ensuring the IDs are correct, you&#8217;re only left to hook up the <strong>OrderBindingProvider</strong> in your <strong>OrderActivity</strong>. Let&#8217;s do that now.</p><pre class="crayon-plain-tag">[Activity(Label = "Order Form")]
[ImportBinding(typeof(OrderBindingProvider))]
public class OrderActivity : FormActivity&lt;OrderViewModel&gt;
{
    ...
}</pre><p>You&#8217;re done. Run the project and you&#8217;ll get the same result with iOS version.</p>
<div style="width: 400px; " class="wp-video"><video class="wp-video-shortcode" id="video-5101-11" width="400" height="360" loop="1" autoplay="1" preload="auto" controls="controls"><source type="video/mp4" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android.mp4?_=11" /><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android.mp4">http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android.mp4</a></video></div>
<p>&nbsp;</p>
<p>Beautiful, isn&#8217;t it?</p>
<h1>Wrapping Up</h1>
<p>The entire project for this tutorial can be found <a href="http://git.intersoftsolutions.com/projects/CT/repos/crosslightformbuilderextended/browse">here</a>. To use this sample, you&#8217;ll need to use at least Crosslight <a href="http://git.intersoftpt.com/projects/CROS/repos/updates/browse/Crosslight4_0_5000_321">4.0.5000.321</a> and above. Hopefully this will help you learn more about the Crosslight Form Builder.</p>
<p>You&#8217;ve seen how you can easily inject a custom view to the form by using the ViewResource custom editor. Probably some time in the future I&#8217;ll add a custom ViewBuilder tutorial as well. This will be very useful for those of you who wants to build a custom control that works seamlessly with the FormBuilder. We&#8217;ve also used this approach in building Crosslight Form Builder for each platform inside Crosslight framework.</p>
<p>Cheers,<br />
Nicholas Lie</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/11/extending-crosslight-form-builder-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/iOS.mp4" length="608488" type="video/mp4" />
<enclosure url="http://blog.intersoftsolutions.com/wp-content/uploads/2015/11/Android.mp4" length="562423" type="video/mp4" />
		</item>
		<item>
		<title>Editing Data with View Projection</title>
		<link>http://blog.intersoftsolutions.com/2015/08/editing-data-with-view-projection/</link>
		<comments>http://blog.intersoftsolutions.com/2015/08/editing-data-with-view-projection/#comments</comments>
		<pubDate>Thu, 20 Aug 2015 10:40:55 +0000</pubDate>
		<dc:creator><![CDATA[Jimmy Petrus]]></dc:creator>
				<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[2015 R1]]></category>

		<guid isPermaLink="false">http://blog.intersoftsolutions.com/?p=4705</guid>
		<description><![CDATA[In my post last week, I have introduced a truly time-saving feature in Crosslight 4 called view projection. As its name implies, this feature supposed to be used only for data listing/viewing purpose. Typically, you will use a much simple (flat) object model that represents [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="View projection and editing" style="float:right; margin:0 0 10px 10px;" data-attachment-id="4709" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing.png" data-orig-size="1312,1026" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="View projection and editing" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing-300x235.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing-1024x801.png" /><p>In <a href="http://blog.intersoftsolutions.com/2015/08/introducing-crosslight-view-projection/">my post last week</a>, I have introduced a truly time-saving feature in Crosslight 4 called view projection. As its name implies, this feature supposed to be used only for data listing/viewing purpose. Typically, you will use a much simple (flat) object model that represents the shape of data which can be conveniently bound to the list view. However, the flattened object does no longer represent the actual hierarchy of your data, thus making it non suitable for editing. That said, how can we handle data editing scenario? Is it possible to enable data editing while leveraging view projection? Read on.</p>
<p>The quick answer is yes — data editing can be used together with view projection, but we&#8217;ll get there a bit later. When using view projection, we suggest that you load only necessary data that is actually used in the list view. Since the loaded data is not designed to be editable, the best practice for data editing is to reload the data complete with the related entities on demand, typically when user tapped on the cell to navigate. Thanks to the full-fledged app framework and entity services in Crosslight, that can be easily done in the <em>Navigated</em> method of EditorViewModel instance, like so:</p><pre class="crayon-plain-tag">public async override void Navigated(NavigatedParameter parameter)
{
    base.Navigated(parameter);

    if (parameter.Data != null)
    {
        this.ActivityPresenter.Show("Loading");
        this.IsDataLoading = true;

        // reload item along with the specified navigation properties
        await this.Repository.GetSingleAsync((parameter.Data as SalesOrderHeader).SalesOrderID, new string[] { "Customer", "Address1", "SalesOrderDetails", "SalesOrderDetails.Product" });

        // call OnItemChanging so the recently fetched related entities can be tracked after item reloading
        this.OnItemChanging(this.Item, this.Item);

        this.IsDataLoading = false;
        this.ActivityPresenter.Hide();
    }
}</pre><p>The above code is quite self explanatory. It will asynchronously load the entity along with the related entities given its primary key value when the editor view is navigated. The essence of the above code lies in the <a href="http://developer.intersoftsolutions.com/display/crosslightapi/IAsyncDataRepository(TEntity)+Interface" target="_blank">GetSingleAsync method</a> which now has a new overload that accepts an array of related properties to be reloaded along with the entity in one shot. That&#8217;s really intuitive.</p>
<p>To improve performance, it&#8217;s wise to load the entity only when it’s navigated the first time. That’s pretty easy to implement, let’s make changes to the code like this:</p><pre class="crayon-plain-tag">public async override void Navigated(NavigatedParameter parameter)
{
    base.Navigated(parameter);

    if (parameter.Data != null)
    {
        // only load additional data if it hasn't been loaded previously
        if (this.Item.Customer == null)
        {
            this.ActivityPresenter.Show("Loading");
            this.IsDataLoading = true;

            // reload item along with the specified navigation properties
            await this.Repository.GetSingleAsync((parameter.Data as SalesOrderHeader).SalesOrderID, new string[] { "Customer", "Address1", "SalesOrderDetails", "SalesOrderDetails.Product" });

            // call OnItemChanging so the recently fetched related entities can be tracked after item reloading
            this.OnItemChanging(this.Item, this.Item);

            this.IsDataLoading = false;
            this.ActivityPresenter.Hide();
        }
    }
}</pre><p>Piece of cake. Now, if the properties of the entity has changed, or the related entities have changed during editing, the changes won’t sync back to the list view. That’s actually normal, because the objects in the list view is no longer related to the entities being edited. Remember the code we wrote above? We reloaded the entity specifically for editing purpose during navigation.</p>
<p>There’s where the new <a href="http://developer.intersoftsolutions.com/display/crosslightapi/IEntityExtensions+Class+-+AppFramework?src=search" target="_blank">entity.UpdateProperties()</a> API comes to rescue. Simply call the API on the edited entity, it will automatically scan the changes and reflect them back to the projected properties. And even better, if you’ve upgraded to Crosslight 4’s Enterprise App Framework, then you have zero line of code to write. That’s made possible because the API is now baked to the <a href="http://git.intersoftpt.com/projects/CROS/repos/frameworks/browse/Intersoft.AppFramework/ViewModels.Infrastructure/DataEditorViewModelBase.cs" target="_blank">DataEditorViewModelBase class</a>, specifically in the <em>OnDataChanged</em> method. Here’s the code snippet for your convenience:</p><pre class="crayon-plain-tag">/// Called when a data item is changed.
protected override void OnDataChanged(TModel item)
{
    IEntity entity = this.Item as IEntity;
    if (entity != null)
        entity.UpdateProperties();

    base.OnDataChanged(item);
}</pre><p>And here&#8217;s the result as expected using the view projection samples:</p>
<p><a href="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing.png"><img class="alignnone size-large wp-image-4709" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/View-projection-and-editing-1024x801.png" alt="View projection and editing" width="604" height="472" /></a></p>
<p>You might be wondering how the <em>UpdateProperties</em> API does its magic. How does it know which related entities have changed and which projected properties to sync back? The answer lies in the Crosslight&#8217;s powerful data framework which has complete information about the entity&#8217;s relationships and its metadata as well as built-in changes management.</p>
<blockquote><p>If you haven&#8217;t familiar with Crosslight data framework — or haven&#8217;t used it yet, I strongly recommend you to start using it. Learn more <a href="http://developer.intersoftsolutions.com/display/crosslight/Building+Business+Apps+with+Enterprise+App+Framework" target="_blank">here</a>.</p></blockquote>
<p>Now, let&#8217;s pull the <a href="http://git.intersoftpt.com/projects/CROS-SUPP/repos/view-projection-samples/browse" target="_blank">data samples</a> from our Git and see the editing in action with view projection. Run the sample in either iOS and Android platform, tap on a cell, edit some fields, i.e., City, then save it. Go back to the list view, voila, the changes are sync&#8217;ed back as expected, just as if it were an entity loaded with navigational properties.</p>
<p>In this post, we&#8217;ve looked at how a data-driven Crosslight app is built, covering both data list and editing by combining view projection and entity&#8217;s API. Now you also have better understanding on how Crosslight is designed to provide great developer experiences by eliminating much of the boilerplate code, so you can focus on the code that matters to your business apps. If you&#8217;ve any questions, we&#8217;d be happy to welcome you aboard on <a href="http://intersoftsolutions.com/community/crosslight" target="_blank">our community forum</a>.</p>
<p>Best,<br />
Jimmy</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/08/editing-data-with-view-projection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Crosslight View Projection</title>
		<link>http://blog.intersoftsolutions.com/2015/08/introducing-crosslight-view-projection/</link>
		<comments>http://blog.intersoftsolutions.com/2015/08/introducing-crosslight-view-projection/#comments</comments>
		<pubDate>Mon, 10 Aug 2015 11:05:42 +0000</pubDate>
		<dc:creator><![CDATA[Jimmy Petrus]]></dc:creator>
				<category><![CDATA[2015 R1]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Crosslight]]></category>
		<category><![CDATA[Data Access]]></category>
		<category><![CDATA[view projection]]></category>
		<category><![CDATA[webapi]]></category>

		<guid isPermaLink="false">http://blog.intersoftpt.com/?p=4670</guid>
		<description><![CDATA[Couple weeks ago, we&#8217;ve finally released Premier Studio 2015, one of our most remarkable milestones. We shipped Crosslight 4 with a host of new exciting components, Visual Studio 2015 across all product lineup, and Windows Edge support for WebUI components. That&#8217;s not all. We also [...]]]></description>
				<content:encoded><![CDATA[<img width="604" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/Screen-Shot-2015-08-10-at-6.30.25-PM-604x270.png" class="attachment-post-thumbnail wp-post-image" alt="Order list" style="float:right; margin:0 0 10px 10px;" data-attachment-id="4674" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/Screen-Shot-2015-08-10-at-6.30.25-PM.png" data-orig-size="750,490" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Order list" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/Screen-Shot-2015-08-10-at-6.30.25-PM-300x196.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2015/08/Screen-Shot-2015-08-10-at-6.30.25-PM.png" /><p>Couple weeks ago, we&#8217;ve finally released Premier Studio 2015, one of our most remarkable milestones. We shipped Crosslight 4 with a host of new exciting components, Visual Studio 2015 across all product lineup, and Windows Edge support for WebUI components. That&#8217;s not all. We also launched a fully redesigned website which was the result of months of redesign works. In case you missed the news, check out the full coverage on the release <a href="http://blog.intersoftpt.com/2015/07/intersoft-studio-2015-delivers-hundreds-new-features-and-enhancements-to-crosslight-asp-net-and-clientui/" target="_blank">here</a>, and the website redesign concept <a href="http://blog.intersoftpt.com/2015/07/intersoftwebsite-reimagined/" target="_blank">here</a>.</p>
<p>So now you&#8217;ve got the new Studio installed, what&#8217;s next? We&#8217;ve made available a wealth of resources to help you quickly get started. For the starting point, I recommend you to check out the <a href="http://developer.intersoftpt.com/display/crosslight/Crosslight+4.0+Release+Notes" target="_blank">release notes</a> and follow the links in the page. Over the next few weeks, we&#8217;ll blog around the new features introduced in this release, covering each of them in more practical way.</p>
<p>This week, I&#8217;d like to discuss about the new features in Crosslight data access components, and how you can leverage them to build faster, more reliable data intensive apps.</p>
<p>Displaying a list of data that includes information from several related tables is a very typical application scenario. Consider the order list in an order tracking app, it makes a good sense to show aggregated amount and shipping information along with the order item, perhaps something like this.</p>
<p><img class="alignnone size-full wp-image-4674" src="http://blog.intersoftpt.com/wp-content/uploads/2015/08/Screen-Shot-2015-08-10-at-6.30.25-PM.png" alt="Order list" width="375" /></p>
<p>Showing the list from orders table only is certainly straightforward, but how to include the related information? That&#8217;s easy, thanks to the data service component (both client &amp; server) included in Crosslight. Just use the <em>Includes</em> API in the query definition, so the related entities will be fetched automatically from the server, like so:</p><pre class="crayon-plain-tag">public override QueryDescriptor GetQueryDescriptor()
{
    QueryDescriptor queryDescriptor = this.GetBaseQueryDescriptor();
    queryDescriptor.Includes.Add("Customer");
    queryDescriptor.Includes.Add("Address1");

    return queryDescriptor;
}</pre><p>That works well in most cases, particularly for list with few included related entities. However, when you added more related entities to the list, the payload will become larger too, exponentially. This often leads to issues like: longer time to transfer the data, more overhead in entity processing, and more critically, larger memory allocation. But, that&#8217;s all natural due to the way related entities work. To understand how a response with related entities look like, take a look at the JSON below.</p><pre class="crayon-plain-tag">{
  "$id": "1",
  "$type": "Intersoft.Data.WebApi.QueryResult, Intersoft.Data.WebApi.v4",
  "AffectedRows": null,
  "InlineCount": null,
  "Results": [
    {
      "$id": "2",
      "Address1": {
        "$id": "3",
        "AddressID": 1092,
        "AddressLine1": "99700 Bell Road",
        "AddressLine2": null,
        "City": "Auburn",
        "StateProvince": "California",
        "CountryRegion": "United States",
        "PostalCode": "95603",
        "rowguid": "79cdd89c-3c91-48db-8277-46d04aad7251",
        "ModifiedDate": "2002-09-01T00:00:00.000",
        "CompleteAddress": "99700 Bell Road\nAuburn, California"
      },
      "Customer": {
        "$id": "4",
        "CustomerID": 29847,
        "NameStyle": false,
        "Title": "Mr.",
        "FirstName": "David",
        "MiddleName": null,
        "LastName": "Hodgson",
        "Suffix": null,
        "CompanyName": "Good Toys",
        "SalesPerson": "adventure-works\\linda3",
        "EmailAddress": "david16@adventure-works.com",
        "Phone": "969-555-0117",
        "PasswordHash": "+gtwbVycsIIj2loVtrHNRN6IBLl20lQpRK8+JhzxyEo=",
        "PasswordSalt": "AwqZdYk=",
        "rowguid": "fdd7d9cb-9a81-40fc-baf6-facde8da4923",
        "ModifiedDate": "2002-09-01T00:00:00.000"
      },
      "SalesOrderID": 71774,
      "RevisionNumber": 2,
      "OrderDate": "2015-06-01T00:00:00.000",
      "DueDate": "2015-06-13T00:00:00.000",
      "ShipDate": "2015-06-08T00:00:00.000",
      "ModifiedDate": "2015-06-08T00:00:00.000"
    }
}</pre><p>As seen in the above JSON, every included entity will be added as a child record in the server response. This allows the Crosslight entity manager to attach the records properly in the client side. In our simple test, the order list retrieved with the Includes approach took <a href="https://gist.github.com/jimmyps/f2e3968436ca1e66d2fd#file-salesorderheaders_includes-json" target="_blank">72 KB</a> in size.</p>
<blockquote><p>If you&#8217;re new to Crosslight or unfamiliar with the QueryDescriptor API, you might want to check out <a href="http://developer.intersoftpt.com/display/crosslight/Dynamic+Data+Access+with+Query+Descriptor" target="_blank">Dynamic Data Access with Query Descriptor</a>.</p></blockquote>
<p>Obviously, you can address the above issues with custom server query or custom views, which are well supported by Crosslight. But, creating custom query every time you need to display data is counter-productive and tedious at best, agree?</p>
<p>So what solution do we have in store? Read on.</p>
<h2>Enter View Projection.</h2>
<p>Building on our experiences in architecting large scale enterprise apps, and also based on our customer&#8217;s feedback, we are introducing a more efficient way to create a shaped view in Crosslight 4. Called view projection, you can easily create a data view comprised of various information from related tables into a single flat list – dramatically shrinking payload size and processing time. We believe this is a better, more efficient, and more reliable way to fetch and present data in Crosslight apps.</p>
<p>Using the same order list scenario above, we can now extend the order entity with new properties to contain the additional information we&#8217;d like to fetch, then simply add the new <em>Select</em> attribute to indicate which property and related table to fetch, like so:</p><pre class="crayon-plain-tag">public partial class SalesOrderHeader
{
    [Select("Address1.CompleteAddress")]
    public string ShipAddress { set; get; }

    [Select("Customer.CompanyName")]
    public string CustomerCompany { set; get; }
}</pre><p>By defining such a simple metadata in the client side, the server will automatically construct the query behind the scene. Back in the client, you&#8217;ll get the data with the additional information in a flat list, then simply bind it to a list view. Piece of cake.</p>
<p>Here&#8217;s the example result of the response.</p><pre class="crayon-plain-tag">{
  "$id": "1",
  "$type": "Intersoft.Data.WebApi.QueryResult, Intersoft.Data.WebApi.v4",
  "AffectedRows": null,
  "InlineCount": null,
  "Results": [
    {
      "$id": "2",
      "$type": "ViewProjectionSample.DomainModels.SalesOrderHeader, ViewProjectionSample.DomainModels",
      "SalesOrderID": 71774,
      "RevisionNumber": 2,
      "OrderDate": "2015-06-01T00:00:00.000",
      "DueDate": "2015-06-13T00:00:00.000",
      "ShipDate": "2015-06-08T00:00:00.000",
      "ModifiedDate": "2015-06-08T00:00:00.000",
      "SalesOrderDetails": [ ], 
      "Address": null,
      "Address1": null,
      "Customer": null,
      "ShipAddress": "99700 Bell Road\nAuburn, California",
      "CustomerCompany": "Good Toys"
    }
}</pre><p>As expected, the <em>Customer</em> and <em>Address</em> entities are no longer included in the returned result. Instead, the <em>ShipAddress</em> and <em>CustomerCompany</em> properties are simply filled with the requested information.</p>
<p>Per our test using the same order query, the view projection took only <a href="https://gist.github.com/jimmyps/ed2985415448d922c4dd#file-salesorderheaders_viewprojection-json" target="_blank">37 KB</a>, about half the size of the response size using Includes approach. If you build relatively complex data apps, this view projection alone could reduce the response size up to 75%.</p>
<p>That&#8217;s not all. Nested properties is also supported, so you can easily include any entity regardless of the depth, as long as their relationships are well defined. Here&#8217;s an example of nested property selection.</p><pre class="crayon-plain-tag">[Select("Product.Category.CategoryName")]
public string ProductCategory { set; get; }

[Select("Order.ShipToAddress.Country.Name")]
public string ShipCountry { set; get; }</pre><p>In addition to nested properties, the new Select attribute is also smart enough to do some heavy data aggregation and calculation. Say you want to include the order details count and total to the order list, you can specify the Select attribute like this:</p><pre class="crayon-plain-tag">[Select("SalesOrderDetails.OrderQty", Aggregate.Sum)]
public int ProductQuantity { set; get; }</pre><p>As expected, the returned result will look something like this:</p><pre class="crayon-plain-tag">{
  "$id": "1",
  "$type": "Intersoft.Data.WebApi.QueryResult, Intersoft.Data.WebApi.v4",
  "AffectedRows": null,
  "InlineCount": null,
  "Results": [
    {
      "$id": "2",
      "$type": "ViewProjectionSample.DomainModels.SalesOrderHeader, ViewProjectionSample.DomainModels",
      "SalesOrderID": 71774,
      "RevisionNumber": 2,
      "OrderDate": "2015-06-01T00:00:00.000",
      "DueDate": "2015-06-13T00:00:00.000",
      "ShipDate": "2015-06-08T00:00:00.000",
      "ModifiedDate": "2015-06-08T00:00:00.000",
      "SalesOrderDetails": [ ], 
      "Address": null,
      "Address1": null,
      "Customer": null,
      "ShipAddress": "99700 Bell Road\nAuburn, California",
      "CustomerCompany": "Good Toys",
      "ProductQuantity": 2
    }
}</pre><p>Unbelievably simple, isn&#8217;t it? We haven&#8217;t quite finished yet, read on.</p>
<p>How about using some mathematical operations along with the data aggregate, you asked. Well, we&#8217;ve got those covered too. Here&#8217;s a quick example:</p><pre class="crayon-plain-tag">[Select("SalesOrderDetails", "OrderQty * UnitPrice * (1 - UnitPriceDiscount)", Aggregate.Sum)]
public double SubTotal { set; get; }</pre><p>In addition to sum, as you might already have in mind, we also supported other aggregate options such as count, min, max, and average.</p>
<p>And if you just realized, we haven&#8217;t touch the server part even a bit, are we missing something? Nope. The server recognizes all these new Select metadata, thanks to the much improved WebApi component introduced in the new <a href="http://developer.intersoftpt.com/display/crosslightapi/Intersoft.Data.WebApi.v4+Assembly" target="_blank">Intersoft.Data.WebApi.v4</a> assembly.</p>
<blockquote><p>In fact, all you have to do at the server side is to update the Intersoft WebApi assemblies and the related Nuget packages to the latest version. Check out this <a href="http://developer.intersoftpt.com/display/crosslight/Crosslight+4+Upgrade+Guide" target="_blank">upgrade guide</a> for details.</p></blockquote>
<p>Last but not least, all the powerful new capabilities above are equally supported in Crosslight SQLite as well, so if you build sync-aware apps, the same metadata will work just fine, whether the app loads data from the remote server or local storage. In addition, the view projection has been carefully designed to support data editing and update scenario as well which I&#8217;ll cover in the next post.</p>
<p>We&#8217;ve designed Crosslight with strong focus on developer experience since the initial release. We continue to provide even greater developer experience in this new release, making the impossible possible with intuitive and simple API design.</p>
<p>We still have a lot of stories to cover around data access improvements, but for now, let&#8217;s pull <a href="http://git.intersoftpt.com/projects/CROS-SUPP/repos/view-projection-samples/browse" target="_blank">some samples</a> and see the demo of view projection features for yourself. If you have any questions, join us in <a href="http://intersoftpt.com/community/crosslight" target="_blank">our community forum</a>.</p>
<p>Best,<br />
Jimmy</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2015/08/introducing-crosslight-view-projection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create Drill Down Chart with UXChart</title>
		<link>http://blog.intersoftsolutions.com/2013/03/create-drill-down-chart-with-uxchart/</link>
		<comments>http://blog.intersoftsolutions.com/2013/03/create-drill-down-chart-with-uxchart/#comments</comments>
		<pubDate>Tue, 05 Mar 2013 03:24:03 +0000</pubDate>
		<dc:creator><![CDATA[yanesblog]]></dc:creator>
				<category><![CDATA[2012 R2]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Charting]]></category>
		<category><![CDATA[ClientUI]]></category>
		<category><![CDATA[Drilldown]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[UXChart]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">https://intersoftpt.wordpress.com/?p=3025</guid>
		<description><![CDATA[Quite often, you will need to allow your user to drill-down data from yearly data to monthly or from categories to individual items. Now it’s very easy with our new concept which gives you freedom to create unlimited levels of drill-down charts from a single [...]]]></description>
				<content:encoded><![CDATA[<img width="466" height="270" src="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/chart01_thumb1-604x350.png" class="attachment-post-thumbnail wp-post-image" alt="Drill down chart" style="float:right; margin:0 0 10px 10px;" data-attachment-id="4101" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/chart01_thumb1.png" data-orig-size="642,365" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="Drill down chart" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/chart01_thumb1-300x170.png" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/chart01_thumb1.png" /><p>Quite often, you will need to allow your user to drill-down data from yearly data to monthly or from categories to individual items. Now it’s very easy with our new concept which gives you freedom to create unlimited levels of drill-down charts from a single data source in minutes.</p>
<p>In this blog post, I want to show an example of drilling down chart data, i.e. to display master-detail data in the same chart, by clicking a point of the first series will let another series shown, which represents detailed data related to the selected point. This is critical for creating interesting and fun charts to interact with. This blog entry includes basic knowledge of what you can do with our chart right out of the box. See the following screenshot for the drilling down chart that we want to create.</p>
<p><a href="http://intersoftpt.files.wordpress.com/2013/03/chart01.png"><img title="Drill down chart" style="background-image:none;padding-top:0;padding-left:0;display:inline;padding-right:0;border-width:0;" border="0" alt="Drill down chart" src="http://intersoftpt.files.wordpress.com/2013/03/chart01_thumb.png" width="642" height="365"></a></p>
<p>To get started, we use the <b>Child</b> properties in UXChart to specify which chart that we want to display as detail of origin chart. Specifically, all charting collections must be defined in View in a first place. On first load, you are allowed to display one chart only, and the others’ visibility must be set to collapse. See the code below:</p>
<p></p><pre class="crayon-plain-tag">&lt;dataVisualisation:UXChart x:Name="Chart1" Visibility="Visible" Child="{Binding ElementName=Chart2}"
                        DrillDownCommand="{Binding DrillDownCommand}"&gt;
&lt;/dataVisualisation:UXChart&gt;

&lt;dataVisualisation:UXChart x:Name="Chart2" Visibility="Collapsed"  &gt;
&lt;/dataVisualisation:UXChart&gt;</pre><p></p>
<p>Next, we need to hook our custom command to control the drilldown action, we called it <b>DrillDownCommand</b>.</p>
<p></p><pre class="crayon-plain-tag">public DelegateCommand DrillDownCommand { get; set; }</pre><p></p>
<p>And then we assign DrillDownCommand to some execute the method in our ViewModel.</p>
<p></p><pre class="crayon-plain-tag">this.DrillDownCommand = new DelegateCommand(ExecuteDrillDown);</pre><p></p>
<p>In the execute method, we can initialize the data from the data source and retrieve detail information about the chart itself.</p>
<p></p><pre class="crayon-plain-tag">private void ExecuteDrillDown(object parameter)
{
   UXChartDrillDownCommandArgs args = parameter as UXChartDrillDownCommandArgs;

   if (args.Level == 1)
   {
     Data parent = args.DataPointContext as Data;
     if (parent != null)
     {
       InitializeDataByArea(parent.Area);
     }
   }
}</pre><p></p>
<p>In conclusion, with simple implementation, we already make drill down function very simple and effortless. Now feel free to try and make your very own drill down chart. There’s unlimited level that you can figure out and explore.</p>
<p>For more information about our ClientUI control in Silverlight &amp; WPF, please refer to the <a href="http://www.intersoftpt.com/Support/ClientUI/Documentation">online documentation</a>. You can download our sample <a href="http://www.intersoftpt.com/tdn/downloads/DrillDownSample.zip">here</a>. Feel free to drop us any questions or feedback.</p>
<p>Till we meet again.</p>
<p>Cheers,<br />Yanes</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2013/03/create-drill-down-chart-with-uxchart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebFileUploader: Store Uploaded Files in Database</title>
		<link>http://blog.intersoftsolutions.com/2013/01/webfileuploader-store-uploaded-files-in-database/</link>
		<comments>http://blog.intersoftsolutions.com/2013/01/webfileuploader-store-uploaded-files-in-database/#comments</comments>
		<pubDate>Thu, 31 Jan 2013 10:30:03 +0000</pubDate>
		<dc:creator><![CDATA[yudhiy]]></dc:creator>
				<category><![CDATA[2012 R2]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[File Uploader]]></category>
		<category><![CDATA[WebUI Studio]]></category>

		<guid isPermaLink="false">https://intersoftpt.wordpress.com/?p=3014</guid>
		<description><![CDATA[Last year I posted an article which showed how to store the files which are uploaded using UXFileUpload (ClientUI control for Silverlight and WPF) in database. In this article, I will show a similar scenario which can be done using WebFileUploader, a member of Intersoft [...]]]></description>
				<content:encoded><![CDATA[<img width="531" height="124" src="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/webfileuploader_thumb1.jpg" class="attachment-post-thumbnail wp-post-image" alt="WebFileUploader" style="float:right; margin:0 0 10px 10px;" data-attachment-id="4100" data-orig-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/webfileuploader_thumb1.jpg" data-orig-size="531,124" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}" data-image-title="WebFileUploader" data-image-description="" data-medium-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/webfileuploader_thumb1-300x70.jpg" data-large-file="http://blog.intersoftsolutions.com/wp-content/uploads/2014/09/webfileuploader_thumb1.jpg" /><p>Last year I posted an article which showed how to store the files which are uploaded using UXFileUpload (ClientUI control for Silverlight and WPF) in database. In this article, I will show a similar scenario which can be done using WebFileUploader, a member of Intersoft Solutions ASP.NET controls.</p>
<p>WebFileUploader is an easy to use; high performance and advanced file upload component which allows you to upload multiple files without page refresh. WebFileUploader uses 100% HTML technology for all its features, and fully supports all modern browsers including Firefox, Safari, Chrome and Opera. Using 100% HTML technology means that WebFileUploader doesn&#8217;t require Flash plug-in to support multiple files uploading and many other features.</p>
<p>This scenario, to store the uploaded files in database, can be divided to two parts. The first part is <strong>to configure WebFileUploader for IIS application</strong>; and the other part, <strong>using server-side code to process uploaded files and store them into database</strong>.</p>
<h2>To configure WebFileUploader for IIS application</h2>
<p>Some configuration is needed in the web.config to run WebFileUploader in IIS. The list below shows how to configure WebFileUploader for IIS 7 application.</p>
<ol>
<li>By default, ASP.NET application restricts maximum request length to 4 MB. To enable our application to accept larger files, please configure the maxRequestLength in web.config to higher value. The maxRequestLength value is measured in kilobytes. Here is a snippet to increase your file size to 100MB. <pre class="crayon-plain-tag">&lt;configuration&gt;
  &lt;system.web&gt;
    &lt;httpRuntime maxRequestLength="102400" /&gt;
  &lt;/system.web&gt;
&lt;/configuration&gt;</pre></p>
<li>Add WebFileUploader handler to &lt;handlers&gt; section under &lt;system.webServer&gt;. Here is the snippet. <pre class="crayon-plain-tag">&lt;add name="WebFileUploaderHttpHandler" verb="GET"
  path="WebFileUploaderHttpHandler.axd"
  type="ISNet.WebUI.WebTextEditor.WebFileUploaderHttpHandler, ISNet.WebUI.WebTextEditor"
  preCondition="integratedMode" /&gt;</pre>
<li>Add WebFileUploader module to &lt;modules&gt; section under &lt;system.webServer&gt; in our project web.config. Here is the snippet. <pre class="crayon-plain-tag">&lt;add name="WebFileUploaderHttpModule" preCondition="managedHandler"
  type="ISNet.WebUI.WebTextEditor.WebFileUploaderHttpModule, ISNet.WebUI.WebTextEditor" /&gt;</pre>
<li>Set maxAllowedContentLength to a higher value, which is measured in bytes, to 100MB in web.config. This attribute specifies the maximum length of content in a request. The default value is 30000000, which is approximately 28.6 MB. <pre class="crayon-plain-tag">&lt;system.webServer&gt;
  &lt;security&gt;
    &lt;requestFiltering&gt;
      &lt;requestLimits maxAllowedContentLength="104857600" /&gt;
    &lt;/requestFiltering&gt;
  &lt;/security&gt;
&lt;/system.webServer&gt;</pre>
<li>Unlock the mode override in applicationHost.config. Open IIS 7 application configuration file, the default location is in C:windowssystem32inetsrvconfig, and change the overrideModeDefault to Allow. <pre class="crayon-plain-tag">&lt;section name="requestFiltering" overrideModeDefault="Allow" /&gt;</pre></li>
</ol>
<p>Save the changes and then try to upload a file. If WebFileUploader has been successfully uploaded the file to the designated folder, it means that we are on half way to achieve the goal and ready to proceed to the next step.</p>
<h2>Using server-side code to process uploaded files and store them into database</h2>
<p>A database, called Files.mdf, is added into the App_Data folder of the web project. This database has Files table which consists of following fields.</p>
<table border="1" cellspacing="0" cellpadding="2" width="359">
<tbody>
<tr>
<th valign="top" width="96">Column Name</th>
<th valign="top" width="123">Data Type</th>
<th valign="top" width="140">Allow Nulls</th>
</tr>
<tr>
<td valign="top" width="96">Id</td>
<td valign="top" width="123">uniqueidentifier</td>
<td valign="top" width="140">False</td>
</tr>
<tr>
<td valign="top" width="96">FileData</td>
<td valign="top" width="123">varbinary(MAX)</td>
<td valign="top" width="140">True</td>
</tr>
<tr>
<td valign="top" width="96">OriginalName</td>
<td valign="top" width="123">nvarchar(50)</td>
<td valign="top" width="140">False</td>
</tr>
<tr>
<td valign="top" width="96">DateCreated</td>
<td valign="top" width="123">datetime</td>
<td valign="top" width="140">False</td>
</tr>
</tbody>
</table>
<p>A Stored Procedure, sprocFilesInsertSingleItem, will be used to insert a single item of file into Files.mdf database.</p>
<p></p><pre class="crayon-plain-tag">INSERT INTO Files
(
	Id,
	FileUrl,
	FileData,
	OriginalName
)
VALUES
(
	@id,
	@FileUrl,
	@FileData,
	@originalName
)</pre><p></p>
<p>Next, we are going to use the <strong>OnAfterUpload</strong> server-side event of WebFileUploader. It is the server-side event which fired when a file upload is succeeded. Generally, there are three processes to be performed on this event.</p>
<ul>
<li>Read and manipulate the uploaded file using FileStream class.
<li>Invoke and execute sprocFilesInsertSingleItem stored procedure to store the uploaded file on Files.mdf database.
<li>Delete the specified file from the UploadPath folder. </li>
</ul>
<p></p><pre class="crayon-plain-tag">protected void WebFileUploader1_AfterUpload(object sender, ISNet.WebUI.WebTextEditor.WebFileUploaderFileEventArgs e)
{
    byte[] fileData = ReadFile(e.WebFileUploadInfo.Path + "\" + e.WebFileUploadInfo.FileName);
    string originalName = e.WebFileUploadInfo.FileName;

    using (SqlConnection mySqlConnection = new SqlConnection(@"Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|Files.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"))
    {
        // Set up the Command object
        SqlCommand myCommand = new SqlCommand("sprocFilesInsertSingleItem", mySqlConnection);
        myCommand.CommandType = CommandType.StoredProcedure;

        // Set up the ID parameter
        SqlParameter prmId = new SqlParameter("@id", SqlDbType.UniqueIdentifier);

        Guid id = Guid.NewGuid();
        prmId.Value = id;
        myCommand.Parameters.Add(prmId);

        // Set up the FileUrl parameter
        SqlParameter prmFileUrl = new SqlParameter("@fileUrl", SqlDbType.NVarChar, 255);

        prmFileUrl.Value = DBNull.Value;
        myCommand.Parameters.Add(prmFileUrl);

        // Set up the FileData parameter
        SqlParameter prmFileData = new SqlParameter("@fileData ", SqlDbType.VarBinary);

        prmFileData.Value = fileData;
        prmFileData.Size = fileData.Length;
        myCommand.Parameters.Add(prmFileData);

        // Set up the OriginalName parameter
        SqlParameter prmOriginalName = new SqlParameter("@originalName", SqlDbType.NVarChar, 50);
        prmOriginalName.Value = e.WebFileUploadInfo.FileName;
        myCommand.Parameters.Add(prmOriginalName);

        // Execute the command, and clean up.
        mySqlConnection.Open();
        bool result = myCommand.ExecuteNonQuery() &gt; 0;
        mySqlConnection.Close();
    }

    File.Delete(e.WebFileUploadInfo.Path + "\" + e.WebFileUploadInfo.FileName);
}

private static byte[] ReadFile(string filePath)
{
    byte[] buffer;
    FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

    try
    {
        int length = (int)fileStream.Length; // get file length
        buffer = new byte[length];           // create buffer
        int count;                           // actual number of bytes read
        int sum = 0;                         // total number of bytes read

        // read until Read method returns 0 (end of the stream has been reached)
        while ((count = fileStream.Read(buffer, sum, length - sum)) &gt; 0)
        {
            sum += count; // sum is a buffer offset for next reading
        }
    }
    finally
    {
        fileStream.Close();
    }

    return buffer;
}</pre><p></p>
<p>That’s it! Now the files uploaded by WebFileUploader control will be stored in database. It’s pretty easy and straightforward, don’t you think so?</p>
<p><a href="http://intersoftpt.files.wordpress.com/2013/01/webfileuploader.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border-width:0;" title="WebFileUploader" border="0" alt="WebFileUploader" src="http://intersoftpt.files.wordpress.com/2013/01/webfileuploader_thumb.jpg" width="531" height="124"></a></p>
<p>Click <a href="http://www.intersoftpt.com/tdn/downloads/WebFileUploader_Sample.zip">here</a> to download the sample and feel free to drop me a line in the comment box if you find this post useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.intersoftsolutions.com/2013/01/webfileuploader-store-uploaded-files-in-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
