Pasando variables de ViewModel a otro View (MVVMCross)
Durante las dos últimas semanas he estado trabajando en el desarrollo de una aplicación multiplataforma (IOS / Android / WP7) utilizando el framework MVVMCross. Hoy me encontré con un problema que realmente no sé cómo resolver, así que espero que pueda empujarme en la dirección correcta.
En el IOS tengo la siguiente construcción para navegar a otra página (el código abajo se encuentra en un ViewModel):
- ¿Cuál es la contraparte de iOS 'QLPreviewController o UIDocumentInteractionController en Android?
- Error de la aplicación multiplataforma de Xamarin Studio
- Problema al instalar el paquete NuGet Xamarin
- Cuando se usa Mono Touch, ¿puedo también empaquetar para una aplicación estándar de Windows?
- Desarrollo de la aplicación C # móvil para ejecutarse en múltiples plataformas
KeyValuePair<string,string> kvpAct1 = new KeyValuePair<string, string>("short", ".countertest5"); public IMvxCommand BeckhoffActuator1 { get { return new MvxRelayCommand<Type>((type) => this.RequestNavigate<Beckhoff.BeckhoffActuatorViewModel>(kvpAct1)); } }
Cuando se dispara esta IMvxCommand (botón pulsado) se carga la siguiente vista, en este caso, el BeckhoffActuatorViewModel. En el código del BeckhoffActuatorView utilizo el keyvaluepair de arriba:
public class BeckhoffActuatorView : MvxTouchDialogViewController<BeckhoffActuatorViewModel> { ICollection<string> icol; public BeckhoffActuatorView(MvxShowViewModelRequest request) : base(request, UITableViewStyle.Grouped, null, true) { icol = request.ParameterValues.Values; } public override void ViewDidLoad() { //Code } }
Esta construcción está funcionando bien en IOS, pero me gustaría usar la misma construcción en mi aplicación Android.
El código en el ViewModel no ha cambiado, ya que es la idea de MVVM. Pero el código del BackhoffActuatorView es diferente para Android:
public class BeckhoffActuatorView : MvxBindingActivityView<BeckhoffSensorViewModel> { public ICollection<string> icol; public BeckhoffActuatorView() { Debug.WriteLine("Standard"); } public BeckhoffActuatorView(MvxShowViewModelRequest request) { Debug.WriteLine("Custom"); icol = request.ParameterValues.Values; } protected override void OnViewModelSet() { SetContentView(Resource.Layout.BeckhoffActuatorView); } }
El código anterior no funciona, el MvxBindingActivityView no parece implementar algo similar al ViewController que utilizo en IOS. El código sólo viene en el constructor estándar, y cuando dejo que uno fuera completamente no compilar / ejecutar.
¿Alguien sabe que puedo acceder al keyvaluepair que envío con el RequestNavigate? ¡Gracias!
- Mono para iOS / Android ¿Abierto o cerrado? ¿Pago o gratis?
- Desarrollar una aplicación C # para Windows Mobile, Android y iPhone
- Desarrollo de iOS y Android en Windows
- Comunicación entre 2 aplicaciones en el mismo dispositivo iOS / Android con Xamarin
- ¿Cómo puedo decirle a mi jefe de trabajo con Xamarin no lo hará más rápido
- No puedo ejecutar la aplicación después de actualizar Xamarin.Forms
- Visual Studio 2015 no instala Android SDK para Xamarin
- El código funciona en Xamarin Android pero no funciona en Java (HttpPost JSON)
MVVMCross está muy basado en convenciones – y funciona en la idea de pasar mensajes entre ViewModels siempre que sea posible.
Si navega a un ViewModel utilizando:
KeyValuePair<string,string> kvpAct1 = new KeyValuePair<string, string>("short", ".countertest5"); public IMvxCommand BeckhoffActuator1 { get { return new MvxRelayCommand<Type>((type) => this.RequestNavigate<Beckhoff.BeckhoffActuatorViewModel>(kvpAct1)); } }
Entonces usted debería ser capaz de recoger eso en el BeckhoffActuatorViewModel usando el constructor:
public class BeckhoffActuatorViewModel : MvxViewModel { public BeckhoffActuatorViewModel(string short) { ShortValue = short; } private string _shortValue; public string ShortValue { get { return _shortValue; } set { _shortValue = value; FirePropertyChanged("ShortValue"); } } }
Y sus vistas pueden entonces tener acceso a ViewModel.ShortValue
(para iOS esto se puede hacer después de base.ViewDidLoad (), para Android después de OnCreate () y para WP7 después de OnNavigatedTo)
Para un ejemplo de esto, eche un vistazo al ejemplo de TwitterSearch:
Esto tiene un HomeViewModel que llama navegar usando:
private void DoSearch() { RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText }); }
Y un TwitterViewModel que recibe el searchTerm usando el constructor:
public TwitterViewModel(string searchTerm) { StartSearch(searchTerm); }
Tenga en cuenta que sólo se permiten string
s en este paso de mensaje en la actualidad – pero siempre puede serializar sus propios objetos utilizando JSON.Net – o puede extender el marco – es de código abierto.
Tenga en cuenta que sólo las string
s, int
s, double
s y bool
s están permitidas en este parámetro de constructor que pasa actualmente – esto se debe a los requisitos de serialización para Xaml Urls y para Android Intents. Si desea experimentar con la navegación utilizando sus propios objetos serializados personalizados, consulte http://slodge.blogspot.co.uk/2013/01/navigating-between-viewmodels-by-more.html .
Además, tenga en cuenta que si desea utilizar la navegación anónima de objetos ( RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });
), entonces tendrá que asegurarse de que un atributo InternalsVisibleTo
está establecido – ver https://github.com /slodge/MvvmCrossTwitterSearch/blob/master/TwitterSearch.Core/Properties/AssemblyInfo.cs :
[assembly: InternalsVisibleTo("Cirrious.MvvmCross")]
Además … no para los débiles … y esto no es "buen código mvvm" … pero si realmente quieres / necesitas acceder a los datos de MvxShowViewModelRequest dentro de una actividad de Android, entonces puedes extraerla de la Intención entrante – hay una cadena de Extras que contiene la solicitud (consulte la deserialización en CreateViewModelFromIntent
en https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Android/Views/MvxAndroidViewsContainer.cs )