在WPF-MVVM中保存并关闭当前窗口

时间:2015-03-24 15:40:05

标签: c# wpf mvvm mvvm-light

我有两个按钮Save,Save&在我的窗口关闭。如果用户单击“保存”,我可以成功保存详细信息。当用户点击“保存”时,我无法弄清楚如何关闭窗口。关。这是我的保存代码

<telerik:RadButton x:Name="button_Save" Content="Save" Command="{Binding SaveProductCommand}" CommandParameter="{Binding ElementName=ProductName, Path=Text}" />

这是我的接力命令。

public ICommand SaveProductCommand
{
  get 
  {
    return new RelayCommand<string>(SaveProductExecute);
  } 
 }

我的第一个问题:

我们可以为Save和Save&amp; Close传递一个或多个参数True或false吗?这样我们只能使用一个Relay Command吗?

第二个问题:

如何在保存后关闭当前窗口?

3 个答案:

答案 0 :(得分:2)

好问题。这里的关键是使用Action。看看我的样本

我们会尽量将编码保持在最低限度。

  

我们可以为Save和Save&amp; Close传递一个或多个参数True或false吗?这样我们只能使用一个Relay Command吗?

由于你没有提到你传递的是真是假,我已经包含了一个包含两个字符串项TrueFalse的列表框。

如果选择true,则只执行一部分命令,如果选择false,我们将执行命令中的两种方法。

  1. 使用按钮列表框

    创建视图
      <ListBox x:Name="items">
        <System:String>True</System:String>
        <System:String>False</System:String>
      </ListBox>
    
    <Button Content="MyButton" Command="{Binding Path=MyCustomCommand}" 
    CommandParameter="{Binding SelectedItem,ElementName=items}"/> 
    
  2. 创建ViewModel,即 MyViewModel.cs

    public class MyViewModel : INotifyPropertyChanged
    {
    
       public Action CloseAction { get; set; }
       public ICommand MyCustomCommand { get; set; }
    
    
       public MyViewModel()
       {
          MyCustomCommand = new RelayCommand(new Action<object>(MyFunction));
       }
    
    
       private void MyFunction(object MyCommandParameter)
       {
        if (Convert.ToString(MyCommandParameter) == "True")
        {
            MessageBox.Show("Save Executed");
        }
        else
        {
            MessageBox.Show("Save Execcuted");
            CloseAction();
        }
    }
    
  3. 在View Codebehind中

      public partial class MainWindow : Window
      {
         public MainWindow()
         {
            InitializeComponent();
            MyViewModel mv = new MyViewModel();
            this.DataContext = mv;
    
            if (mv.CloseAction == null)
                mv.CloseAction = new Action(() => this.Close());
          }
      }
    

答案 1 :(得分:0)

回答你的2个问题 -

是的,你可以多重绑定......做这样的事情......

<Button.CommandParameter>
    <MultiBinding>
         <Binding Path="path" ElementName="elementName"/>
         <Binding Path="path2" ElementName="elementName2"/>
    </MultiBinding>
</Button.CommandParameter>

有多种关闭窗口的方法,请查看herehere

答案 2 :(得分:0)

考虑利用带参数的消息传递来在对象之间传递数据。

您可以使用EventAggregatorMessageBus

我们的想法是让您的用户控件订阅他们想要响应的事件。

注:

我使用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);
    }
}