MVVM de Josh Smith

L'implémentation du modèle MVVM qu'en a fait Josh Smith se trouve autrement appelé dans le codeplex : MVVM Foundation

http://bubbleburst.codeplex.com/
Un projet de jeux avec des balles ou des bulles que l'on fait disparaître lorsque l'on clique sur des bulles de la même couleur. Utilise la DLL :  MvvmFoundation.Wpf.dll
et une autre DLL : Thriple.dll

http://mvvmfoundation.codeplex.com/
Le framework MVVM écris par Josh Smith

http://joshsmithonwpf.wordpress.com/2009/07/11/one-way-to-avoid-messy-propertychanged-event-handling/
Forum, discussion sur la façon de traiter proprement les événements PropertyChanged

Principes du MVVM de Josh Smith

Le modèle MVVM de Josh Smith repose sur la création de quatre classes :

ObservableObject : classe de base des ViewModel ou de tous types qui doit fournir des notifications de PropertyChange, implémente l'interface INotifyPropertyChanged. Cette classe peut se nommer à l'usage ViewModelBase.
protected void RaisePropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName); // Debug purpose

PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}

RelayCommand : Dérive de l'interface ICommand et permet d'implémenter les Commands
public class RelayCommand : ICommand
{
readonly Action _execute;
readonly Func<bool> _canExecute;

public RelayCommand(Action execute) : this(execute, null)
{
}

public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");

_execute = execute;
_canExecute = canExecute;
}

public void Execute(object parameter)
{
_execute();
}
}

public class RelayCommand<T> : ICommand
{
        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }
       ...
}

PropertyObserver : Une méthode standard pour gérer l'événement INotifyPropertyChanged.PropertyChanged des autres objets. Cette classe utilise des références faibles (weak references) et le pattern weak-event pour éviter les fuites de mémoire !
public class PropertyObserver<TPropertySource> : IWeakEventListener where TPropertySource : INotifyPropertyChanged
{
public PropertyObserver(TPropertySource propertySource)
{
if (propertySource == null)
throw new ArgumentNullException("propertySource");

_propertySourceRef = new WeakReference(propertySource);
_propertyNameToHandlerMap = new Dictionary<string, Action<TPropertySource>>();
}
       ...
}

Messenger : Mécanisme léger de passage de messages entre les différents ViewModel basé sur l'implémentation du pattern Mediator.
public class Messenger
{
public void Register(string message, Action callback)
{
this.Register(message, callback, null);
}

public void Register<T>(string message, Action<T> callback)
{
this.Register(message, callback, typeof(T));
}

void Register(string message, Delegate callback, Type parameterType)
{
if (String.IsNullOrEmpty(message))
throw new ArgumentException("'message' cannot be null or empty.");

if (callback == null)
throw new ArgumentNullException("callback");

this.VerifyParameterType(message, parameterType);

_messageToActionsMap.AddAction(message, callback.Target, callback.Method, parameterType);
}

public void NotifyColleagues(string message, object parameter)
{
if (String.IsNullOrEmpty(message))
throw new ArgumentException("'message' cannot be null or empty.");

Type registeredParameterType;
if (_messageToActionsMap.TryGetParameterType(message, out registeredParameterType))
{
if (registeredParameterType == null)
throw new TargetParameterCountException(string.Format("Cannot pass a parameter with message '{0}'. Registered action(s) expect no parameter.", message));
}

var actions = _messageToActionsMap.GetActions(message);
if (actions != null)
actions.ForEach(action => action.DynamicInvoke(parameter));
}

...
}

Utilisation de MVVM Foundation

TBC (To Be Continued)

Aucun commentaire:

Enregistrer un commentaire

Pour plus d'interactivité, n'hésitez pas à laisser votre commentaire.