2015-04-01 34 views
0

我在WPF-MVVM應用程序中將用戶控件顯示爲對話框。這是代碼。關閉MVVM中的WPF用戶控件彈出菜單

var ProductView = new Product(); 
    var ProductViewModel = new ProductViewModel(); 
    ProductView.DataContext = ProductViewModel; 
    this.ShowDialogWindow("Add Product", ProductView); 

這ShowDialogWindow方法是這樣的

protected void ShowDialogWindow(string header, UserControl control) 
{ 
     RadWindow window = new RadWindow(); 
     window.Owner = App.Current.MainWindow; 
     window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; 
     window.Content = control;   
     window.Header = header; 
     window.CanClose = true; 
     window.ResizeMode = ResizeMode.NoResize; 
     window.ShowDialog(); 
} 

現在,我在DialogWindow用戶控制按鈕 「關閉」。如何使用該按鈕關閉窗口?

注意:這是一個WPF用戶控件而不是窗口。我只想使用MVVM關閉

+0

你說這是不是一個窗口,但ShowDialog的創建,並顯示一個窗口。你是否想讓視圖模型關閉一個視圖?如果是這樣,我建議使用中介模式來發送和訂閱消息,類似的東西在這裏討論:http://www.codeproject.com/Articles/35277/MVVM-Mediator-Pattern – 2015-04-01 16:23:49

+0

@PaulGibson顯示的窗口也是用戶控制 – Chatra 2015-04-01 16:24:42

回答

1

考慮利用帶參數的消息傳遞來在對象之間傳遞數據。可以使用EventAggregatorMessageBus

您可以從Nuget拉入MessageBus。

然後,您可以使用MessageBus.Instance進行訂閱和發佈。

這個想法是讓您的用戶控件訂閱他們想要回復的事件。

注意:

我用viewmodels做到這一點。 但是,我認爲將這些代碼添加到用戶控件時會產生代碼異味,而這些用戶控件是爲了具有通用性而不管使用它們的應用程序。

我使用發佈訂閱模式複雜類的依賴關係:

視圖模型:

public class ViewModel : ViewModelBase 
    { 
     public ViewModel() 
     { 
      CloseComand = new DelegateCommand((obj) => 
       { 
        MessageBus.Instance.Publish(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, null); 
       }); 
     } 
} 

窗口:

public partial class SomeWindow : Window 
{ 
    Subscription _subscription = new Subscription(); 

    public SomeWindow() 
    { 
     InitializeComponent(); 

     _subscription.Subscribe(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED, obj => 
      { 
       this.Close(); 
      }); 
    } 
} 

您可以利用Bizmonger.Patterns來獲取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 
} 

}

認購

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

您正在談論窗口。我明確提到我正在使用用戶控制。對於Window,我可以看到this.close(),但對於用戶控件,有Close()方法 – Chatra 2015-04-01 16:36:18

+0

對話框無論其內容如何都是「清晰」的窗口。窗口是您有能力關閉的控件。 – 2015-04-01 16:37:59

+0

我明白,但下面的代碼。用戶控件沒有this.close()。 _subscription.Subscribe(Messages.REQUEST_DEPLOYMENT_SETTINGS_CLOSED,OBJ => { this.Close(); }); – Chatra 2015-04-01 16:39:53