How to create a sort of UserControl in Android Xamarin
<p>I've been reading tutorials and articles on how to create a sort of <code>UserControl</code> for Android Xamarin and I still have no clue on how to do it due to the poor explanation of those tutorials/articles or due to the lack of examples.</p>

<p>What I need is to create an <code>UserControl</code> that will hold some info about a store ( an image, store name, store address, store contact, and a few more details, but these should be enough to build a sample here ).</p>

<p>ASCII Sample:</p>

<pre><code>+-----------------------------------+
| +----------+                      |
| |/ / / / / |  STORE NAME          |
| | / / / / /|                   \  |
| |/ / / / / |  STORE ADDRESS     &gt; |
| | / / / / /|                   /  |
| |/ / / / / |  STORE CONTACT       |
| +----------+                      |
+-----------------------------------+
</code></pre>

<p>Now, how would I build this on Android Xamarin? I get that, from the tutorials I've seen, I need a layout and a <em>code-behind</em> (<em>duh!</em>), but exactly which one - <code>Activity</code> or <code>Fragment</code>? Even though in the Visual Studio when I'm editing the layout file it shows the layout within a phone frame that doesn't mean that I'm building an page layout rather that the <code>UserControl</code> layout?</p>

<hr>

<h1>Solution found</h1>

<p>With the answer given by Jon Douglas, I was able to do what I wanted.</p>

<p>I'll leave here the sample code necessary to replicate the layout I've made above and some explanation - maybe it can help someone later.</p>

<p>To the store buttons list I needed to create 4 files:</p>

<ul>
<li>The <code>Button</code> layout <strong>template</strong>, which would hold the structure of the button;</li>
<li>The <code>ListView</code> <strong>adapter</strong>, which will contain the code necessary to the initialization of the <code>ListView</code> and events;</li>
<li>The Stores <strong>layout</strong>, which will have basically only a <code>ListView</code> that will be populated with a list of Stores;</li>
<li>The Stores <strong>fragment</strong>, which will have the logic when this specific fragment is used.</li>
</ul>

<blockquote>
  <p>Although I'm using fragments, I don't think this would be that much difference between an sample using activities.</p>
</blockquote>

<hr>

<h2>Button Layout Template</h2>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- The root of the layout --&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingLeft="5dp"
     android:paddingRight="5dp" &gt;

    &lt;!-- Needed to add the elements side-by-side,
        for some reason didn't work to me setting
        the `orientation` on the root layout --&gt;
    &lt;LinearLayout
         android:orientation="horizontal"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="5dp" &gt;

        &lt;!-- The store image --&gt;
        &lt;ImageView
             android:id="@+id/StoreImage"
             android:layout_gravity="top"
             android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="55"
             android:paddingTop="0dp" /&gt;

        &lt;!-- This `LinearLayout` will hold the store name,
             address and contact vertically --&gt;
        &lt;LinearLayout
             android:orientation="vertical"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="100"
             android:layout_marginLeft="15px" &gt;

            &lt;!-- The store name --&gt;
            &lt;TextView
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:textColor="#FFDCBB73"
                 android:id="@+id/StoreName"
                 android:layout_marginBottom="5dp" /&gt;

            &lt;!-- The store address --&gt;
            &lt;LinearLayout
                 android:orientation="horizontal"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" &gt;

                &lt;!-- Store address label --&gt;
                &lt;TextView
                     android:text="@string/AddressText"
                     android:textAppearance="?android:attr/textAppearanceSmall"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:textColor="#FF9D9D9D"
                     android:layout_marginRight="5dp" /&gt;

                &lt;!-- Store address value --&gt;
                &lt;TextView
                     android:textAppearance="?android:attr/textAppearanceSmall"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:textColor="#FF9D9D9D"
                     android:textStyle="bold"
                     android:id="@+id/StoreAddress" /&gt;
            &lt;/LinearLayout&gt;

            &lt;!-- The store contact --&gt;
            &lt;LinearLayout
                 android:orientation="horizontal"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" &gt;

                &lt;!-- Store contact label --&gt;
                &lt;TextView
                     android:text="@string/ContactsText"
                     android:textAppearance="?android:attr/textAppearanceSmall"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:textColor="#FF9D9D9D"
                     android:layout_marginRight="5dp" /&gt;

                &lt;!-- Store contact value --&gt;
                &lt;TextView
                     android:textAppearance="?android:attr/textAppearanceSmall"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:textColor="#FF9D9D9D"
                     android:textStyle="bold"
                     android:id="@+id/StoreContacts" /&gt;
            &lt;/LinearLayout&gt;
        &lt;/LinearLayout&gt;

        &lt;ImageView
             android:src="@drawable/arrowright"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_marginRight="5dp"
             android:paddingRight="5dp"
             android:paddingLeft="5dp"
             android:id="@+id/StoreEntry_ViewStore" /&gt;
    &lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;
</code></pre>

<h2>ListView Adapter</h2>

<pre><code>using Android.App;
using Android.Graphics;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Project {
    public class ListViewAdapter : BaseAdapter&lt;StoreObject&gt; {
        // Properties
        private Activity Context {
            get; set;
        }
        private List&lt;StoreObject&gt; StoresList {
            get; set;
        }

        // Methods
        public override Int32 Count {
            get {
                return StoresList.Count;
            }
        }
        public override Int64 GetItemId( Int32 position ) {
            return position;
        }
        public override StoreObject this[ Int32 position ] {
            get {
                return StoresList[ position ];
            }
        }


        public override View GetView( Int32 position, View convertView, ViewGroup parent ) {
            StoreObject
                 store = StoresList[ position ];

            View
                 view = convertView ?? Context.LayoutInflater.Inflate( Resource.Layout.StoreEntry, null );

            // Set the store image
            Double
                 imageWidth = Context.Resources.DisplayMetrics.WidthPixels / Context.Resources.DisplayMetrics.Density * (3.0 / 7.0);

            Bitmap
                 storeBitmap = Utils.GetBitmap( store.Image, (Int32) imageWidth );

            view.FindViewById&lt;ImageView&gt;( Resource.Id.StoreImage ).SetImageBitmap( storeBitmap );

            // Set the store name
            view.FindViewById&lt;TextView&gt;( Resource.Id.StoreName ).SetText( store.Name, TextView.BufferType.Normal );

            // Set the store schedule, whether is open or closed
            String
                 storeSchedule = store.isOpen ?
                      Context.Resources.GetString( Resource.String.OpenText ) :
                      Context.Resources.GetString( Resource.String.ClosedText );

            view.FindViewById&lt;TextView&gt;( Resource.Id.StoreSchedule ).SetText( storeSchedule, TextView.BufferType.Normal );

            // Set the store address
            String
                 storeLocation = Context.Resources.GetString( Resource.String.NotAvailableText );

            if (store.Address != null) {
                storeLocation = store.Address.City;
            }

            view.FindViewById&lt;TextView&gt;( Resource.Id.StoreAddress ).SetText( storeLocation, TextView.BufferType.Normal );

            // Set the store contact
            String
                 storeContact = Context.Resources.GetString( Resource.String.NotAvailableText );

            if (store.contacts != null &amp;&amp; store.contacts.Count &gt; 0) {
                storeContact = store.contacts.FirstOrDefault().PhoneNumber.ToString();
            }

            view.FindViewById&lt;TextView&gt;( Resource.Id.StoreContacts ).SetText( storeContact, TextView.BufferType.Normal );

            return view;
        }

        // Constructors
        public ListViewAdapter( Activity context, List&lt;StoreObject&gt; items ) : base() {
            Context = context;
            StoresList = items;
        }
    }
}
</code></pre>

<h2>Stores Fragment Layout</h2>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;ListView xmlns:android="http://schemas.android.com/apk/res/android"
     android:minWidth="25px"
     android:minHeight="25px"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:id="@+id/StoresHolder"
     android:listSelector="#7FDCBB73" /&gt;
</code></pre>

<h2>Stores Fragment</h2>

<pre><code>using System;
using System.Collections.Generic;
using System.Diagnostics;

using Android.App;
using Android.OS;
using Android.Views;
using Android.Widget;

namespace Project {
    public class Stores : Fragment {
        // Properties
        private List&lt;StoreObject&gt; StoresList {
            get; set;
        }

        private View CurrentView {
            get; set;
        }
        private ListView StoresHolder {
            get {
                return CurrentView.FindViewById&lt;ListView&gt;( Resource.Id.StoresHolder );
            }
        }

        // Events
        public override void OnCreate( Bundle savedInstanceState ) {
            base.OnCreate( savedInstanceState );
        }
        public override View OnCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
            base.OnCreateView( inflater, container, savedInstanceState );

            CurrentView = inflater.Inflate( Resource.Layout.Stores, container, false );

            if (StoresList == null) {
                StoresList = GetStores();
            }

            StoresHolder.ItemClick += ItemClick;

            StoresHolder.Adapter = new ListViewAdapter( Activity, StoresList );

            return CurrentView;
        }

        private void ItemClick( Object sender, AdapterView.ItemClickEventArgs e ) {
            // Do stuff...
        }
    }
}
</code></pre>

<p>I hope that this can help someone in the future.</p>