0

In my view I have:

<Button Grid.Column="2" x:Name="BackBtn" Content="Powrót" Command="{Binding ClickCommand}" Width="100" Margin="10" HorizontalAlignment="Right"/>

Then, in ViewModel :

public ICommand ClickCommand
{
    get
    {

        return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), _canExecute));
    }
}

private void MyAction()
{
    MainWindow mainWindow = new MainWindow(); // I want to open new window but how to close current?
    mainWindow.Show();
    // how to close old window ?
}

namespace FirstWPF
{
    public class CommandHandler : ICommand
    {
        private Action _action;
        private bool _canExecute;
        public CommandHandler(Action action, bool canExecute)
        {
            _action = action;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _action();
        }
    }
}

I have no idea how to manage that problem, I want to close current window form ViewModel, because I am opening a new one.

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
mike_pl
  • 121
  • 1
  • 2
  • 12
  • Are you saying you want to call `Application.Current.MainWindow.Close();` before you open the new window? – 15ee8f99-57ff-4f92-890c-b56153 Mar 03 '17 at 17:40
  • Just a side note -- It's quite useless to say something "doesn't work". That could mean anything. You tried to call Close() (on what object?) and it "didn't work": Did it throw an exception? Did the compiler tell you it wasn't a member of the mysterious secret unknown object you tried to call it on? Or what? Things can "not work" in any number of ways. Say which. – 15ee8f99-57ff-4f92-890c-b56153 Mar 03 '17 at 17:43
  • Doesn't work means that nothing happens – mike_pl Mar 03 '17 at 19:20
  • How is your CommandHandler class implemented? – mm8 Mar 03 '17 at 21:15
  • this may also be interesting for you: http://stackoverflow.com/questions/419596/how-does-the-wpf-button-iscancel-property-work – Felix D. Mar 03 '17 at 21:35

1 Answers1

10

You can design your window to take in context object that is used to signal a close request

public interface ICloseable
{
    event EventHandler CloseRequest;
}

public class WindowViewModel : BaseViewModel, ICloseable
{
    public event EventHandler CloseRequest;
    protected void RaiseCloseRequest()
    {
        var handler = CloseRequest;
        if (handler != null) handler(this, EventArgs.Empty);
    }
}


public partial class MainWindow : Window
{
    public MainWindow(ICloseable context)
    {
        InitializeComponent();
        context.CloseRequest += (s, e) => this.Close();
    }
}
grek40
  • 13,113
  • 1
  • 24
  • 50
  • I am sure there is simpler solution for that – mike_pl Mar 03 '17 at 20:49
  • 1
    @mike_pl u want to decouple your code from your UI so they don't know each other (MVVM)... That's a really neat solution to do so ... – Felix D. Mar 03 '17 at 21:24
  • why public MainWindow(ICloseable context) { InitializeComponent(); context.CloseRequest += (s, e) => this.Close(); } It deosnt have non-parameter constructor ?? Now I can't create this window in another place, what should I put to create that Main Window? – mike_pl Mar 03 '17 at 21:48
  • https://bitbucket.org/michal_be/firstwpf/src/98318a8a282afd96fa4b6200751db2c3e64687f7/FirstWPF/?at=master Here Is my code, please make it working if you could :/ – mike_pl Mar 03 '17 at 21:49
  • Now I cannot create this object of MainWindow() in other place, because i don't know what to pass as parameter to it's constructor... – mike_pl Mar 03 '17 at 21:56
  • You are free to provide another constructor that doesn't take an `ICloseable`. My answer is just showing __one way__ to make it possible for a viewmodel to request the window closing and for the window to actually fulfill this request. It doesn't mean you would no longer be allowed to construct windows that can't be closed from the viewmodel, to register the context by other means than the constructor or to code whatever you want. You didn't yet explain much about your MVVM starting code (where and how is the viewmodel created and connected to the view, ...?) so my solution might not be best. – grek40 Mar 03 '17 at 23:11
  • It's not working, old window is still opened despite I call RaiseCloseRequest() method.. – mike_pl Mar 04 '17 at 14:20
  • a few comments above I pasted link to my repo where is whole code, so you can directly try it... – mike_pl Mar 04 '17 at 14:22
  • Normally I don't look at external full project code unless I'm convinced that the asker already provided all useful information in the question and I still have to look up some specifics. So please try to compress your problem into an [MCVE example code](http://stackoverflow.com/help/mcve) and add it to your question. This is mainly because it will help you to get a better understanding about your actual problem and the focus of your question. Also, if I just try to solve whatever issue your full code has, it will not be useful to others with a similar problem. – grek40 Mar 04 '17 at 14:48
  • @mike_pl I don't know if you were able to resolve this problem or not. But at least I tried to debug with this solution and found out that CloseRequest event was null when you call RaiseCloseRequest in VM. I solved it by adding this.DataContext = ctx in MainWindow constructor. This way the DataContext is aware of the CloseRequest event. – popsiporkkanaa Sep 19 '18 at 07:13