简体   繁体   English

在MVVM中关闭WPF用户控件弹出窗口

[英]Close WPF User Control Popup in MVVM

I am showing User Control as Dialog in WPF-MVVM application. 我在WPF-MVVM应用程序中将用户控件显示为对话框。 Here is the code. 这是代码。

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

and this ShowDialogWindow Method is like this 这个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();
 }

Now, I have a button "Close" in the DialogWindow User Control. 现在,我在DialogWindow用户控件中有一个“关闭”按钮。 How can I close window using that button ? 如何使用该按钮关闭窗口?

NOTE: This is a WPF User Control not Window. 注意:这是WPF用户控件而不是窗口。 I want to close using MVVM only 我只想使用MVVM关闭

Consider leveraging messaging with parameters to pass around data between your objects. 考虑利用带参数的消息传递在对象之间传递数据。

You can use an EventAggregator or MessageBus . 您可以使用EventAggregatorMessageBus

You can pull in the MessageBus from Nuget . 您可以从Nuget插入MessageBus。

You can then do a subscribe and publish using MessageBus.Instance. 然后,您可以使用MessageBus.Instance进行订阅和发布。

The idea is to have your user controls subscribe to events that they would like to respond to. 想法是让您的用户控件订阅他们想要响应的事件。

NOTE: 注意:

I do this with viewmodels. 我用viewmodels做到这一点。 However, I think it is a code-smell when adding this code to user-controls that are meant to have general use regardless of the application employing them. 但是,我认为在将此代码添加到旨在具有普遍用途的用户控件时,这是一种代码气味,而与使用它们的应用程序无关。

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. 您可以利用Bizmonger.Patterns获取MessageBus。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM