2015-04-23 84 views
10

我正在構建一個需要動態生成和綁定Spinner控件的跨平臺應用程序。我能夠在iOS和Windows平臺上做到這一點,但在Android上遇到問題。如果我理解正確,我必須將一些參數傳遞給構造函數MvxSpinner - context和attrs,但我無法弄清楚我該怎麼做,以及應該通過那裏。另外,我不知道如何綁定ItemsSource和SelectedItem。我想一個新的綁定集必須被創建(類似於iOS版本),但我無法在Android上找到它。你能給我一些指導嗎?以編程方式在MvvmCross中創建和綁定Android Spinners

下面是從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, 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(); 
     } 
+1

https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs#L138和https://github.com/MvvmCross/MvvmCross-Tutorials/blob /master/ApiExamples/ApiExamples.Droid/Resources/Layout/Test_Spinner.axml#L11 - 兩者都使用數據綁定而不是代碼隱藏。 – Stuart

+0

謝謝Stuart,它給了我問題的數據綁定部分的解決方案,但我現在仍然在代碼中以編程方式創建MvxSpinner時遇到了問題。如何做到這一點?應該傳遞給它的構造函數? –

回答

2

這裏是如何通過代碼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

+0

謝謝你的迴應,唯一缺少的是LayoutInflaterProvider類型,如何訪問它? –

+0

哎呀抱歉,這實際上是它自己的自定義類。你可以在這裏找到它:https://github.com/MvvmCross/MvvmCross-Tutorials/blob/386d6b7e672e3289f6227255180b15bbd89f1534/CrossLight/PluginUse/Mvvm/Framework/LayoutInflaterProvider.cs。我也會更新我的答案。 – PkL728

相關問題