A Start...
I was looking for an implementation using the MVVMCross pattern. I found something very close in https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/ApiExamples. The touch project contains the FirstView.cs
Line 144: | |
public override void ViewDidLoad() | |
{ | |
base.ViewDidLoad(); | |
var picker = new UIPickerView(); | |
var pickerViewModel = new MvxPickerViewModel(picker); | |
picker.Model = pickerViewModel; | |
picker.ShowSelectionIndicator = true; | |
var textView = new UITextField(new RectangleF(10, 100, 300, 30)); | |
Add(textView); | |
textView.InputView = picker; | |
var label = new UILabel(new RectangleF(10, 130, 300, 30)); | |
Add(label); | |
var set = this.CreateBindingSet<SpinnerView, SpinnerViewModel>(); | |
set.Bind(pickerViewModel).For(p => p.SelectedItem).To(vm => vm.SelectedItem); | |
set.Bind(pickerViewModel).For(p => p.ItemsSource).To(vm => vm.Items); | |
set.Bind(textView).To(vm => vm.SelectedItem); | |
set.Bind(label).To(vm => vm.SelectedItem); | |
set.Apply(); | |
} |
This gets us part of the way there but what this binding does is simply bring up the picker view and displays the 4 options in the Model. The PickerView contains no way to exit out of the control except using the default back in the iOS navigation bar. This is not going to work for my use case. I needed to have a way to close out the pickerview once the selection had been made.
Getting Closer ...
Over at 13daysaweek blog I stumbled across the article Combobox Type Input With iOS and MonoTouch "Combobox Type Input With iOS and MonoTouch". This is trying to solve the problem I was having but it was not using MVVM. It was however critical to understanding that the UITextField has two properties which allow a user to associate the pickerview with the textview object. The properties:
- TextField.InputView
- TextField.InputAccessoryView
"I noticed another interesting property on the UITextField class, InputAccessoryView. It turns out that if a view is assigned to this property, it will be displayed above the view specified by the InputView property. With that in mind, I created a UIToolBar, added a button and set that as the InputAccessorView. "
A Solution ...
So combining both the approaches yielded the following solution
public override void ViewDidLoad() | |
{ | |
base.ViewDidLoad(); | |
var picker = new UIPickerView(); | |
var pickerViewModel = new MvxPickerViewModel(picker); | |
picker.Model = pickerViewModel; | |
picker.ShowSelectionIndicator = true; | |
var textView = new UITextField(new RectangleF(10, 100, 300, 30)); | |
Add(textView); | |
UIToolbar = new UIToolbar(); toolbar.BarStyle = UIBarStyle.Black; toolbar.Translucent = true; toolbar.SizeToFit(); UIBarButtonItem doneButton = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done, (s, e) => { //This dismisses the picker view and returns control to the main screen. textView.ResignFirstResponder(); } toolbar.SetItems(new UIBarButtonItem[] { doneButton }, true); //This associates the picker view with the textview textView.InputView = picker; //This will insert the toolbar into the pickerview. This will allow the user to dismiss the //view once a choice has been made. | |
textView.InputAccessoryView = toolbar; | |
var set = this.CreateBindingSet<SpinnerView, SpinnerViewModel>(); | |
set.Bind(pickerViewModel).For(p => p.SelectedItem).To(vm => vm.SelectedItem); | |
set.Bind(pickerViewModel).For(p => p.ItemsSource).To(vm => vm.Items); | |
set.Bind(textView).To(vm => vm.SelectedItem); | |
set.Bind(label).To(vm => vm.SelectedItem); | |
set.Apply(); | |
} |
The toolbar control has been added so that a user selecting from the picker view can close the view once they have selected the value. This allows the control to be more standalone as it does not depend on the navigation bar as the original code base provided in the MVVM sample. The critical element in the view is the remember to assign the ResignFirstResponder method to the doneButton action. If you do not do this then the activation of the done button will not close the PickerView leaving the user stranded on the control.
Source:
- https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs
- http://thirteendaysaweek.com/2012/09/19/combobox-type-input-with-ios-and-monotouch/
- https://github.com/13daysaweek/MonoTouchUIPickerView
- http://forums.xamarin.com/discussion/5805/uipickerview-example
Got a lot of tips and advice those solve existing Xamarin Developer issue and with possible best solution for a simple ComboBox for MVVMCross (Xamarin).
ReplyDeleteThank you for the giveaway!