我正在构建一个需要动态生成和绑定Spinner控件的跨平台应用程序.我能够在iOS和
Windows平台上做到这一点,但是与
Android有关系.如果我正确理解,我必须向MvxSpinner的上下文和attrs的构造函数传递一些参数,但是我无法弄清楚我该怎么做,应该在那里传递什么.另外,我不知道如何绑定ItemsSource和SelectedItem.我想要创建一个新的绑定集(与iOS版本相似),但是我无法在Android上找到它.你能给我一些方向吗
这是我的源代码从Windows版本:
private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message ) { ColourAtlas selected = message.SelectedColourAtlas; var vm = viewmodel as ColorMatchviewmodel; List<ComboBox> newComboBoxes = new List<ComboBox>(); var currentCount = ColourPickersContainer.Children.Count; for ( int i = currentCount; i < message.ColourCodePartCount; i++ ) { ComboBox cb = new ComboBox { Margin = new Thickness( 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 > 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 > 0 ) { ( DataContext as ColorMatchviewmodel ).ColourCodePartChangedCommand.Execute( changedIndex ); } }
而这里是iOS版本(或多或少是同样的事情 – 虽然它只是清除现有的旋转器,而不是重用它们):
private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message ) { ColourAtlas selected = message.SelectedColourAtlas; ClearPickers(); var currentSet = this.CreateBindingSet<ColorMatchView,ColorMatchviewmodel>(); for ( int i = 0; i < 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 => t.Text ).To( "SelectedColourCodeParts[" + i + "]" ); currentSet.Bind( pickerviewmodel ).For( p => p.ItemsSource ).To( "ColourPartLists[" + i + "]" ); currentSet.Bind( pickerviewmodel ).For( p => p.SelectedItem ).To( "SelectedColourCodeParts[" + i + "]" ); currentSet.Bind( pickerviewmodel ).For( p => p.SelectedChangedCommand ).To( vm => 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(); }
我现在的Android版本的部分(而不是功能)大纲如下:
private void InputColourAtlasChangedMessageHandler( InputColourAtlasChangedMessage message ) { ColourAtlas selected = message.SelectedColourAtlas; var layout = FindViewById<LinearLayout>( Resource.Id.spinnerList ); ClearPickers(); for ( int i = 0; i < 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<LinearLayout>( Resource.Id.spinnerList ); foreach ( var spinner in _spinners ) { spinner.ItemSelected -= spinner_ItemSelected; } layout.RemoveAllViews(); _spinners.Clear(); }
解决方法
以下是关于如何通过Activity.OnCreate中的代码创建mvxspinner的示例:
_bindingContext = new MvxAndroidBindingContext(this,new LayoutInflaterProvider(LayoutInflater),_viewmodel); var view = (LinearLayout)_bindingContext.BindingInflate(Resource.Layout.Main,null); SetContentView(view); var spinner = new MvxSpinner(this,null,new MvxAdapter(this,_bindingContext)); view.AddView(spinner);
那么如果你想要你的LayoutInflaterProvider可能看起来像这样:
public class LayoutInflaterProvider : IMvxLayoutInflater { public LayoutInflaterProvider(LayoutInflater layoutInflater) { LayoutInflater = layoutInflater; } public LayoutInflater LayoutInflater { get; private set; } }
我最初是在看这个tutorial.