2013-07-05 15 views
5

Come si può associare un comando a un pulsante nel codice in MvvMCross (Xamarin.iOS) con la specifica di un parametro di comando?MvvMCross comando di bind con parametro (nel codice C#)

// command definition 
public MvxCommand SaveDealerDataCommand 
{ 
    get { return new MvxCommand<bool>(DoSaveDealerDataAction); } 
} 

public void DoSaveDealerDataAction(bool show) 
{ 
    //... 
} 

// binding 
bindingset.Bind(saveButton).To(vm => vm.SaveDealerDataCommand); 

Dove è possibile specificare il parametro (vero/falso) che verrà passato al comando?

risposta

8

I pulsanti Android e iOS non hanno le proprietà CommandParameter nello stesso modo di quelle di Windows.

Tuttavia, MvvmCross ha recentemente introdotto un modo per introdurre CommandParameter attacchi tramite convertitori di valore - vedi http://slodge.blogspot.co.uk/2013/06/commandparameter-binding.html

Questa associazione dovrebbe funzionare come:

bindingset 
    .Bind(saveButton) 
    .To(vm => vm.SaveDealerDataCommand) 
    .WithConversion("CommandParameter", true);  

o:

bindingset 
    .Bind(saveButton) 
    .To(vm => vm.SaveDealerDataCommand) 
    .WithConversion(new MvxCommandParameterValueConverter(), true);  

Si noti che questo bind di CommandParameter non è completamente nel pacchetto 3.0.8.1 che è la versione stabile di nuget, quindi per fare questo lavoro y ou può avere bisogno di uno:

  1. Aggiungi questo manuale di registrazione del convertitore di valori nei tuoi Setup.cs

    protected override void FillValueConverters(IMvxValueConverterRegistry registry) 
    { 
        base.FillValueConverters(registry); 
        registry.AddOrOverwrite(
         "CommandParameter", 
         new Cirrious.MvvmCross.Binding.MvxCommandParameterValueConverter() 
        ); 
    } 
    
  2. O utilizzare uno dei pacchetti di beta Nuget caricati dal 3.0.8.1 (set NuGet includere prerelease per vedere questi pacchetti).

  3. O costruire la fonte da soli

+2

C'è un nuovo aggiornamento per questa risposta? Mi piacerebbe avere un parametro di comando dinamico in iOS per il mio UIButton. Ad esempio, quando fai clic sul pulsante, chiamerà il mio comando con il testo corrente in uno dei miei controlli UITextField ... e tutti collegati con .Bind. – Michael

1

Per raggiungere il vostro parametro di comando dinamica utilizzando il testo in uno dei controlli UITextField, si potrebbe associare il testo in quella UITextField a una proprietà di stringa su di voi ViewModel e il codice che viene eseguito nel comando associato al pulsante sarà in grado di accedere al valore tramite tale proprietà quando viene eseguito.

Nella tua ViewController, qualcosa di simile:

UITextField textField = new UTextField(); 
textField.Frame = new RectangleF(0,0,120,30); 
Add(textField); 
UIButton button = new UIButton(); 
button.Frame = new RectangleF(70,40,50,30); 
button.SetTitle("Click Me"); 
Add(button); 

var bindingSet = this.CreateBindingSet<MyView, MyViewModel>(); 
bindingSet.Bind(textField).To(vm => vm.StringProperty); 
bindingSet.Bind(button).To(vm => vm.ClickCommand); 
bindingSet.Apply(); 

Poi, nel vostro ViewModel:

private string _stringProperty = string.Empty; 
public string StringProperty 
{ 
    get { return _stringProperty; } 
    set 
    { 
     _stringProperty = value; 
     RaisePropertyChanged(() => StringProperty); 
    } 
} 
public ICommand ClickCommand 
{ 
    get 
    { 
     return new MvxCommand(HandleClick); 
    } 
} 

public void HandleClick() 
{ 
    //Code that accesses StringProperty (which contains the UITextField's value) 
} 
+0

Ciao, mi spiace, ma questo non si adatta al mio problema (* da 1 anno fa *). La domanda ha mirato i parametri di comando. –

+0

Spiacente, stavo tentando di rispondere alla domanda posta da Michael nel commento sotto il tuo post originale. – jyarnott

0

per passare un parametri di comando dinamici al comando nel modello di visualizzazione è possibile creare una nuova classe per esempio simili DynamicCommandParameterValueConverter:

/// <summary> 
    /// This class is inspired by MvvmCross MvxCommandParameterValueConverter, 
    /// but because we need dynamic command parameters, we need to implement our own combined with a CustomMvxWrappingCommand. 
    /// </summary> 
    /// <typeparam name="T">The type of the 'selected item' for the command</typeparam> 
    /// <typeparam name="TResult">The returned result that is used as input for the command.</typeparam> 
    public class DynamicCommandParameterValueConverter<T, TResult> : MvxValueConverter<ICommand, ICommand> 
    { 
     private readonly Func<T, TResult> commandParameterExpression; 

     public DynamicCommandParameterValueConverter(Func<T, TResult> commandParameterExpression) 
     { 
      this.commandParameterExpression = commandParameterExpression; 
     } 

     protected override ICommand Convert(ICommand value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return new CustomMvxWrappingCommand<T, TResult>(value, commandParameterExpression); 
     } 
    } 

Il CustomMvxWrappingCommand prende un Func come argomento, e viene successivamente richiamato e passato attraverso i comandi CanExecute/Execute metodo. Ecco un frammento di come parte di quella classe potrebbe apparire come:

public void Execute(object parameter) 
     { 
      if (wrapped == null) 
      { 
       return; 
      } 

      if (parameter != null) 
      { 
       Mvx.Warning("Non-null parameter overridden in MvxWrappingCommand"); 
      } 

      wrapped.Execute(commandParameterOverride((T)parameter)); 
     } 

Si potrebbe modificare la classe MvxWrappingCommand da MVX per implementare l'esempio precedente.

L'uso di tutto:

  set.Bind(myControl).For(control => control.ItemClick).To(vm => vm.MyCommand).WithConversion(
      new DynamicCommandParameterValueConverter<MyModel, string>((MyModel item) => 
      { 
       // Do custom logic before parsing the item.. 
      }));