title: Xamarin Forms : advanced ContentView component with custom renderer
body: <p>I want to implement a kind of "user control" which contains 2 images. When i press on it, images sources are inverted. When i release, images are restored with original sources.
  However, Xamarin tap gesture doesn't manage "pressed" state. So, i have decided to attach pressed and released gestures into the respective native components (Droid, iOS). I thought custom renderer could save me, but it doesn't work at all : in my Droid renderer, "Control" is null, so i can't attach Touch event. Any ideas ?</p>
  
  <p>Here the code of my "user control" component :</p>
  
  <p><strong>XAML</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xam_Test.Views.DoubleImageView"&gt;
      &lt;ContentView.Content&gt;
          &lt;Grid&gt;
              &lt;Grid.ColumnDefinitions&gt;
                  &lt;ColumnDefinition Width="Auto"/&gt;
                  &lt;ColumnDefinition Width="Auto"/&gt;
              &lt;/Grid.ColumnDefinitions&gt;
  
              &lt;Image Source="{Binding FirstImageSource}" Aspect="AspectFit" HeightRequest="{Binding ImageSize}"/&gt;
  
              &lt;Image Grid.Column="1" Margin="10,0,0,0" Source="{Binding SecondImageSource}" Aspect="AspectFit" HeightRequest="{Binding ImageSize}"/&gt;
          &lt;/Grid&gt;
      &lt;/ContentView.Content&gt;
  &lt;/ContentView&gt;
  </code></pre>
  
  <p><strong>Code Behind</strong></p>
  
  <pre><code>public partial class DoubleImageView : ContentView
      {
          public static readonly BindableProperty FirstImageSourceProperty = BindableProperty.Create("FirstImageSource", typeof(string), typeof(DoubleImageView), string.Empty);
          public string FirstImageSource
          {
              set { SetValue(FirstImageSourceProperty, value); }
              get { return (string)GetValue(FirstImageSourceProperty); }
          }
  
  
          public static readonly BindableProperty ImageSizeProperty = BindableProperty.Create("ImageSize", typeof(int), typeof(DoubleImageView), 44);
          public int ImageSize
          {
              set { SetValue(ImageSizeProperty, value); }
              get { return (int)GetValue(ImageSizeProperty); }
          }
  
  
          public static readonly BindableProperty SecondImageSourceProperty = BindableProperty.Create("SecondImageSource", typeof(string), typeof(DoubleImageView), string.Empty);
          public string SecondImageSource
          {
              set { SetValue(SecondImageSourceProperty, value); }
              get { return (string)GetValue(SecondImageSourceProperty); }
          }
  
  
          public ICommand SwitchImageCommand { get; set; }
  
          public DoubleImageView()
          {
              BindingContext = this;
              SwitchImageCommand = new Command&lt;bool&gt;((bool isPressed) =&gt; UpdateImages(isPressed));
              InitializeComponent();
          }
  
          private void UpdateImages(bool isPressed)
          {
              string source;
              if (isPressed)
              {
                  source = SecondImageSource;
                  SecondImageSource = FirstImageSource;
                  FirstImageSource = source;
              }
              else
              {
                  source = FirstImageSource;
                  FirstImageSource = SecondImageSource;
                  SecondImageSource = source;
              }
          }
      }
  </code></pre>
  
  <p><strong>And here my Droid renderer</strong></p>
  
  <pre><code>[assembly: ExportRenderer(typeof(DoubleImageView), typeof(DoubleImageViewRenderer))]
  namespace YourNameSpace.Droid.Renderers
  {
      class DoubleImageViewRenderer : ViewRenderer
      {
          private ICommand _updateUICommand;
  
          protected override void Dispose(bool disposing)
          {
              //MANAGE touch events
              if (_updateUICommand != null)
              {
                  Control.Touch -= Image_Touch;
              }
  
              _updateUICommand = null;
  
              base.Dispose(disposing);
          }
  
          protected override void OnElementChanged(ElementChangedEventArgs&lt;Xamarin.Forms.View&gt; e)
          {
              base.OnElementChanged(e);
  
              if (Control == null)
              {
                  var view = (Context as Activity).LayoutInflater.Inflate(Resource.Layout.doubleimage, this, false);
                  var firstImage = view.FindViewById&lt;ImageView&gt;(Resource.Id.first_imageView);
                  var secondImage = view.FindViewById&lt;ImageView&gt;(Resource.Id.second_imageview);
                  // ??????
                  SetNativeControl(view);
              }
  
              if (Control != null)
              {
                  DoubleImageView formView = (e.NewElement as DoubleImageView);
  
                  ExtractFormData(formView);
  
                  //MANAGE touch events
                  if (_updateUICommand != null)
                  {
                      Control.Touch += Image_Touch;
                  }
              }
          }
  
          private void Image_Touch(object sender, TouchEventArgs e)
          {
              var handled = false;
              if (e.Event.Action == MotionEventActions.Down)
              {
                  _updateUICommand.Execute(true);
                  handled = true;
              }
              else if (e.Event.Action == MotionEventActions.Up)
              {
                  _updateUICommand.Execute(false);
  
                  handled = true;
              }
  
              e.Handled = handled;
          }
  
          /// &lt;summary&gt;
          /// Extract form view data
          /// &lt;/summary&gt;
          /// &lt;param name="formImage"&gt;form view object&lt;/param&gt;
          private void ExtractFormData(DoubleImageView formView)
          {
              _updateUICommand = formView.SwitchImageCommand;
          }
      }
  }
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>Apparently, i have to create an android layout to manage the render of my custom component with SetNativeControl. Here my custom layout.</p>
  
  <pre><code>&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="match_parent"
      android:layout_height="match_parent" &gt;
    &lt;ImageView android:id="@+id/first_imageview"/&gt;
    &lt;ImageView android:id="@+id/second_imageview"/&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>I don't know how to bind my android layout with my form properties.</p>