简体   繁体   中英

Save and Close in Current Window in WPF-MVVM

I have two buttons Save, Save & Close in my window. If user clicks on Save, I am able to successfully save the details. I am unable to figure out on how to close window, when user clicks on Save & Close. Here is my code for Save

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

Here is my Relay Command.

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

My First Question:

Can we pass one more parameter True or false for Save and Save&Close ? So that we can use only one Relay Command for both ?

Second Question:

How to close current Window after Saving ?

Good Question..the key here is to use Action .Take a look at my sample

We will try to keep coding to minimal..

Can we pass one more parameter True or false for Save and Save&Close ? So that we can use only one Relay Command for both ?

Since you havent mentioned how you are passing true or false I have included a Listbox which has two string items True and False .

If true is selected only one part of command will execute and if false is selected we will perform both the methods in the command.

  1. Create a view with Button and Listbox

      <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. Create ViewModel ie 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. In 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()); } } 

to ans your 2 questions --

yes you can multi bind ... doing something like this ..

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

and there are many ways to close the window please have a look here and here

Consider leveraging messaging with parameters to pass around data between your objects.

You can use an EventAggregator or MessageBus .

The idea is to have your user controls subscribe to events that they would like to respond to.

NOTE:

I do this with 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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