title: Programmatically creating and binding Android Spinners in MvvmCross
body: <p>I am building a cross-platform application that requires dynamically generating and binding Spinner controls. I was able to do that on iOS and Windows platforms, but have issues with Android. If I understand it correctly, I have to pass some arguments to the constructor of <strong>MvxSpinner</strong> - context and attrs, but I am not able to figure out how can I do that and what should be passed there. Also, I don't know how to then bind the ItemsSource and SelectedItem. I suppose a new binding set has to be created (similarly to the iOS version), but I am not able to figure it out on Android. Can you please give me some directions?</p>
  
  <p>Here is my source code from Windows version:</p>
  
  <pre><code>private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
  {
      ColourAtlas selected = message.SelectedColourAtlas;
      var vm = ViewModel as ColorMatchViewModel;
  
      List&lt;ComboBox&gt; newComboboxes = new List&lt;ComboBox&gt;();
      var currentCount = ColourPickersContainer.Children.Count;
      for ( int i = currentCount; i &lt; message.ColourCodePartCount; i++ )
      {
          ComboBox cb = new ComboBox { Margin = new Thickness( 0, 0, 10, 0 ), PlaceholderText = "choose" };
          Binding itemsSourceBinding = new Binding();
          itemsSourceBinding.Path = new PropertyPath( "ColourPartLists[" + i + "]" );
          Binding selectedItemBinding = new Binding();
          selectedItemBinding.Path = new PropertyPath( "SelectedColourCodeParts[" + i + "]" );
          selectedItemBinding.Mode = BindingMode.TwoWay;
          cb.Tag = i;
          ColourPickersContainer.Children.Add( cb );
          cb.SetBinding( ComboBox.ItemsSourceProperty, itemsSourceBinding );
          cb.SetBinding( ComboBox.SelectedItemProperty, selectedItemBinding );
          cb.SelectionChanged += cb_SelectionChanged;                                
          BindingOperations.SetBinding( cb, ComboBox.SelectedItemProperty, selectedItemBinding );
          newComboboxes.Add( cb );
      }
      while ( ColourPickersContainer.Children.Count &gt; message.ColourCodePartCount )
      {
          ColourPickersContainer.Children.RemoveAt( ColourPickersContainer.Children.Count - 1 );
      }
      _comboboxes = newComboboxes;            
  }
  
  void cb_SelectionChanged( object sender, SelectionChangedEventArgs e )
  {
      var cb = sender as ComboBox;
      int changedIndex = ( int )cb.Tag;
      if ( e.AddedItems.Count &gt; 0 )
      {
          ( DataContext as ColorMatchViewModel ).ColourCodePartChangedCommand.Execute( changedIndex );
      }
  }
  </code></pre>
  
  <p>And here is the iOS version (doing more or less the same thing - although it just clears the existing spinners instead of reusing them):</p>
  
  <pre><code>private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
  {
      ColourAtlas selected = message.SelectedColourAtlas;
      ClearPickers();
      var currentSet = this.CreateBindingSet&lt;ColorMatchView, ColorMatchViewModel&gt;();
      for ( int i = 0; i &lt; message.ColourCodePartCount; i++ )
      {
          var j = i;
          UIPickerView picker = new UIPickerView();
          var pickerViewModel = new MvxPickerViewModel( picker );
          picker.Model = pickerViewModel;
          picker.ShowSelectionIndicator = true;
          pickerViewModel.SelectedItemChanged += vm_SelectedItemChanged;
          var textView = new PaddedUITextField( new RectangleF( 10, 50 + i * 40, 300, 30 ) );
          Add( textView );
          textView.InputView = picker;
          _pickers.Add( picker );
          _textViews.Add( textView );
          currentSet.Bind( textView ).For( t =&gt; t.Text ).To( "SelectedColourCodeParts[" + i + "]" );
          currentSet.Bind( pickerViewModel ).For( p =&gt; p.ItemsSource ).To( "ColourPartLists[" + i + "]" );
          currentSet.Bind( pickerViewModel ).For( p =&gt; p.SelectedItem ).To( "SelectedColourCodeParts[" + i + "]" );
          currentSet.Bind( pickerViewModel ).For( p =&gt; p.SelectedChangedCommand ).To( vm =&gt; vm.ColourCodePartChangedCommand ).CommandParameter( j );
      }
      currentSet.Apply();
      UpdateLayout( View.Frame.Size );
  }
  
  private void ClearPickers()
  {
      foreach ( var picker in _pickers )
      {
          var vm = picker.Model as MvxPickerViewModel;
          vm.SelectedItemChanged -= vm_SelectedItemChanged;
          picker.RemoveFromSuperview();
      }
      foreach ( var textView in _textViews )
      {
          textView.RemoveFromSuperview();
      }
      _pickers.Clear();
      _textViews.Clear();
  }  
  </code></pre>
  
  <p>Partial (and not functional) outline for the Android version I have now is as follows:</p>
  
  <pre><code>private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message )
          {
              ColourAtlas selected = message.SelectedColourAtlas;
              var layout = FindViewById&lt;LinearLayout&gt;( Resource.Id.spinnerList );
              ClearPickers();
  
              for ( int i = 0; i &lt; message.ColourCodePartCount; i++ )
              {
                  MvxSpinner spinner = new MvxSpinner( Context??, Attrs??);
                  MvxAdapter adapter = new MvxAdapter( this );
  
                  spinner.ItemSelected += spinner_ItemSelected;
                  layout.AddView( spinner );
                  _spinners.Add( spinner );
              }
          }
  
          void spinner_ItemSelected( object sender, AdapterView.ItemSelectedEventArgs e )
          {
              var changedIndex = _spinners.IndexOf( sender as MvxSpinner );
              ( DataContext as ColorMatchViewModel ).ColourCodePartChangedCommand.Execute( changedIndex );
          }
  
          private void ClearPickers()
          {
              var layout = FindViewById&lt;LinearLayout&gt;( Resource.Id.spinnerList );
              foreach ( var spinner in _spinners )
              {
                  spinner.ItemSelected -= spinner_ItemSelected;
              }
              layout.RemoveAllViews();
              _spinners.Clear();
          }
  </code></pre>