mvvmlight galasoft c# silverlight windows-phone-7 mvvm-light

galasoft - relaycommand c#



¿Una muestra super simple de MVVM-Light WP7? (2)

Estoy buscando una muestra que demuestre de la manera más liviana posible lo siguiente:

Un modelo que invoca un servicio web basado en SOAP; sondeo regular para obtener el último valor (suponiendo que el servicio SOAP devuelve un valor booleano). El modelo también debe admitir la invocación de un método SOAP que cambie el booleano en el servidor.

Un ViewModel que permite que el booleano subyacente se vincule a controles en la Vista (por ejemplo, a una casilla de verificación).

Una vista con el control de casilla de verificación anterior vinculado al booleano subyacente. Según el intervalo de sondeo, la casilla se actualizará a medida que cambie el estado del servidor. Si se hace clic en la casilla de verificación, el evento se enviará al modelo y el servidor se actualizará.

De manera óptima, esta muestra funcionará en Windows Phone 7, pero en caso de apuro estaré contento con algo que sea compatible con SL3 (no se permite el uso del enrutamiento de comandos de SL4).

Estoy luchando para tratar de entender cómo hacer que MVVM-Light me funcione y sospecho que un experto podría codificar una muestra así rápidamente ... También sospecho que este es un patrón bastante común para muchas aplicaciones.


El puntero de Mick N ayudó, pero lo que realmente me ayudó a superar el problema fue este post de Jeremy Likness: http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html

Aquí está la muestra para el beneficio de los demás (asumiendo que no estoy haciendo nada realmente estúpido):

Primero, comencé a usar el proyecto Mvvm-Light Windows Phone 7.

Agregué una casilla de verificación a mi MainPage.xaml:

<CheckBox Content="Switch 1" IsChecked="{Binding Switch1.PowerState, Mode=TwoWay}" Height="72" HorizontalAlignment="Left" Margin="24,233,0,0" Name="checkBox1" VerticalAlignment="Top" Width="428" />

Observe que IsChecked está obligado a Switch1.PowerState utilizando el modo TwoWay para que la propiedad fluya en ambos sentidos.

Un aprendizaje clave para mí es cómo habilitar la comunicación desde la devolución de llamada de mi temporizador (TimerCB) que se ejecutará en un nuevo subproceso al subproceso de IU de Silverlight. Usé el helper Mvvm-Light DispatcherHelper.CheckBeginInvokeOnUI que espera en el hilo de UI.

Luego tuve que decidir si implementar INotifyPropertyChanged en mi modelo, o usar la implementación ViewModelBase de Mvvm-Light. De hecho, lo intenté en ambos sentidos y lo tuve funcionando, pero decidí que me gustaba usar ViewModelBase porque es compatible con "broadcast" y creo que en mi proyecto real será útil porque tendré múltiples ViewModels. Parece un poco grosero basar un "Modelo" en la clase ViewModelBase, pero no creo que haya ningún daño al hacerlo. (???)

Mi modelo .cs está abajo.

public class OnOffSwitchClass : ViewModelBase // ignore that it''s derived from ViewModelBase! { private const Int32 TIMER_INTERVAL = 5000; // 5 seconds private Timer _timer; // Upon creation create a timer that changes the value every 5 seconds public OnOffSwitchClass() { _timer = new System.Threading.Timer(TimerCB, this, TIMER_INTERVAL, TIMER_INTERVAL); } private static void TimerCB(object state) { // Alternate between on and off ((OnOffSwitchClass)state).PowerState = !((OnOffSwitchClass)state).PowerState; } public const string PowerStatePropertyName = "PowerState"; private bool _myProperty = false; public bool PowerState { get { return _myProperty; } set { if (_myProperty == value) { return; } var oldValue = _myProperty; _myProperty = value; // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging GalaSoft.MvvmLight.Threading.DispatcherHelper.CheckBeginInvokeOnUI(() => RaisePropertyChanged(PowerStatePropertyName, oldValue, value, true)); } } }

MainViewModel.cs se modificó para incluir lo siguiente

private OnOffSwitchClass _Switch1 = new OnOffSwitchClass();

public OnOffSwitchClass Switch1 { get { return _Switch1; } }

Y agregué una llamada a DispatcherHelper.Initialize (); en mi constructor App ().

¿Esto se ve bien?