I use the Publish Subscribe pattern for complicated class-dependencies:
ViewModel:
public class ViewModel : ViewModelBase { public ViewModel() { CloseComand = new DelegateCommand((obj) => { MessageBus.Instance.Publish(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, null); }); } }
Window:
public partial class SomeWindow : Window { Subscription _subscription = new Subscription(); public SomeWindow() { InitializeComponent(); _subscription.Subscribe(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, obj => { this.Close(); }); } }
You can leverage Bizmonger.Patterns to get the MessageBus.
MessageBus
public class MessageBus { #region Singleton static MessageBus _messageBus = null; private MessageBus() { } public static MessageBus Instance { get { if (_messageBus == null) { _messageBus = new MessageBus(); } return _messageBus; } } #endregion #region Members List<Observer> _observers = new List<Observer>(); List<Observer> _oneTimeObservers = new List<Observer>(); List<Observer> _waitingSubscribers = new List<Observer>(); List<Observer> _waitingUnsubscribers = new List<Observer>(); int _publishingCount = 0; #endregion public void Subscribe(string message, Action<object> response) { Subscribe(message, response, _observers); } public void SubscribeFirstPublication(string message, Action<object> response) { Subscribe(message, response, _oneTimeObservers); } public int Unsubscribe(string message, Action<object> response) { var observers = new List<Observer>(_observers.Where(o => o.Respond == response).ToList()); observers.AddRange(_waitingSubscribers.Where(o => o.Respond == response)); observers.AddRange(_oneTimeObservers.Where(o => o.Respond == response)); if (_publishingCount == 0) { observers.ForEach(o => _observers.Remove(o)); } else { _waitingUnsubscribers.AddRange(observers); } return observers.Count; } public int Unsubscribe(string subscription) { var observers = new List<Observer>(_observers.Where(o => o.Subscription == subscription).ToList()); observers.AddRange(_waitingSubscribers.Where(o => o.Subscription == subscription)); observers.AddRange(_oneTimeObservers.Where(o => o.Subscription == subscription)); if (_publishingCount == 0) { observers.ForEach(o => _observers.Remove(o)); } else { _waitingUnsubscribers.AddRange(observers); } return observers.Count; } public void Publish(string message, object payload) { _publishingCount++; Publish(_observers, message, payload); Publish(_oneTimeObservers, message, payload); Publish(_waitingSubscribers, message, payload); _oneTimeObservers.RemoveAll(o => o.Subscription == message); _waitingUnsubscribers.Clear(); _publishingCount--; } private void Publish(List<Observer> observers, string message, object payload) { Debug.Assert(_publishingCount >= 0); var subscribers = observers.Where(o => o.Subscription.ToLower() == message.ToLower()); foreach (var subscriber in subscribers) { subscriber.Respond(payload); } } public IEnumerable<Observer> GetObservers(string subscription) { var observers = new List<Observer>(_observers.Where(o => o.Subscription == subscription)); return observers; } public void Clear() { _observers.Clear(); _oneTimeObservers.Clear(); } #region Helpers private void Subscribe(string message, Action<object> response, List<Observer> observers) { Debug.Assert(_publishingCount >= 0); var observer = new Observer() { Subscription = message, Respond = response }; if (_publishingCount == 0) { observers.Add(observer); } else { _waitingSubscribers.Add(observer); } } #endregion }
}
Subscription
public class Subscription { #region Members List<Observer> _observerList = new List<Observer>(); #endregion public void Unsubscribe(string subscription) { var observers = _observerList.Where(o => o.Subscription == subscription); foreach (var observer in observers) { MessageBus.Instance.Unsubscribe(observer.Subscription, observer.Respond); } _observerList.Where(o => o.Subscription == subscription).ToList().ForEach(o => _observerList.Remove(o)); } public void Subscribe(string subscription, Action<object> response) { MessageBus.Instance.Subscribe(subscription, response); _observerList.Add(new Observer() { Subscription = subscription, Respond = response }); } public void SubscribeFirstPublication(string subscription, Action<object> response) { MessageBus.Instance.SubscribeFirstPublication(subscription, response); } }
IsCancel = "True"on an OK button is a bad idea. That property is for Cancel buttons.closeWindowClickevent handler, notSaveCommand. This appears to be a typo.