2013-07-05 5 views
5

Wie kann ich einen Befehl an eine Schaltfläche in Code in MvvMCross (Xamarin.iOS) mit Angabe eines Befehlsparameters binden?MvvMCross Bindebefehl mit Parameter (in C# -Code)

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

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

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

Wo kann ich den Parameter (true/false) angeben, der an den Befehl übergeben wird?

Antwort

8

Android- und iOS-Tasten haben keine CommandParameter Eigenschaften auf die gleiche Weise wie Windows-Geräte.

jedoch MvvmCross hat vor kurzem eine Art und Weise einführen CommandParameter Bindungen über Wertwandler einführen - siehe http://slodge.blogspot.co.uk/2013/06/commandparameter-binding.html

als Diese Bindung sollte funktionieren:

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

oder:

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

Beachten Sie, dass Diese CommandParameter Bindung ist nicht vollständig im 3.0.8.1-Paket, das die stabile nugget-Version ist, so dass dies y funktioniert ou müssen entweder:

  1. dieses Handbuch Werteumwandler Registrierung Fügen Sie in Ihrem Setup.cs

    protected override void FillValueConverters(IMvxValueConverterRegistry registry) 
    { 
        base.FillValueConverters(registry); 
        registry.AddOrOverwrite(
         "CommandParameter", 
         new Cirrious.MvvmCross.Binding.MvxCommandParameterValueConverter() 
        ); 
    } 
    
  2. Oder Verwendung einer der Beta nuget seit 3.0.8.1 hochgeladen Pakete (set nuget Vorabversionen, um diese Pakete zu sehen).

  3. Oder bauen die Quelle selbst

+2

Gibt es eine neue Aktualisierung dieser Antwort? Ich hätte gerne einen dynamischen Befehlsparameter in iOS für meine UIButton. Wenn Sie zum Beispiel auf die Schaltfläche klicken, würde es meinen Befehl mit dem aktuellen Text in einem meiner UITextField-Steuerelemente aufrufen ... und alle mit .Bind verbunden. – Michael

1

Um die dynamischen Befehlsparameter mit dem Text in einem Ihrer UITextField Kontrollen zu erzielen, könnten Sie den Text in diesem UITextField zu einem String-Eigenschaft auf Sie binden Ansichtsmodell Der Code, der im gebundenen Befehl Ihrer Schaltfläche ausgeführt wird, kann bei der Ausführung über diese Eigenschaft auf den Wert zugreifen.

In Ihrem Viewcontroller, so etwas wie:

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(); 

Dann in Ihrem 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

Hallo, tut mir leid, aber das passt nicht zu meinem Problem (* vor 1 Jahr *). Die Frage zielte auf Befehlsparameter ab. –

+0

Tut mir leid, ich habe versucht, die Frage von Michael in dem Kommentar unter Ihrem ursprünglichen Beitrag zu beantworten. – jyarnott

0

Um einen dynamischen Befehlsparameter auf den Befehl in der View-Modell übergeben Sie eine neue Klasse erstellen können z.B dies wie 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); 
     } 
    } 

Die CustomMvxWrappingCommand nimmt einen Func als Argument und später aufgerufen wird, und in die Befehle CanExecute/Execute Methode übergeben. Hier ist ein Ausschnitt aus wie ein Teil dieser Klasse aussehen könnte:

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)); 
     } 

Sie konnten die MvxWrappingCommand Klasse von MVX ändern das obige Beispiel zu implementieren.

Die Verwendung von allem:

  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.. 
      }));