1

I have a mainwindow, and another window called Loginwindow. In some point this LoginWindow will shows up to get some login info... In the LoginWindow I have a button and it's Command property is binding to OkCommand in the MainViewModel like this:

<Button Content = "Ok" Command="{Binding OkCommand}"/>

In my MainVeiwModel I added a OkCommand RelayCommand

public RelayCommand OkCommand
{
    get { return new RelayCommand(OkClose); }
}

private void OkClose()
{
    MessageBox.Show("Close Login");
}

this code executes well and the MessageBox has appeared when I click the Ok button.. but how do I close the LoginWindow when I click the Ok button...

2 Answers2

1

I propose very simple solution. Don't bind command and simply handle Clicked event in the LoginWindow codebehind. It will be really easy to close the Window from there.

Is there another reason, why you handle OK button in VM of different window?


In XAML (window.xaml):

<Button Content="OK" Click="button1_Click" />

In code behind (window.xaml.cs):

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}
Kugel
  • 19,354
  • 16
  • 71
  • 103
  • so can I add another ViewModel say LoginViewModel to handle LoginWindow or just use the simple code behind, I'm really confused!! – Sami Abdelgadir Mohammed Jan 25 '11 at 03:05
  • If you have LoginWindow class, but if no? I can create Window at runtime, set window.Resources.Source = new Uri("pack://application:,,,/myLoginView.xaml"); then bind view model and ShowDialog. No codebehind. But if you have LoginWindow, and it simple with 2 columns, this approach will be better. – SeeSharp Jan 25 '11 at 04:04
  • This is the correct solution. Accepted answer simply violates MVVM by passing window object into VM. View specific code should always be in view's codebehind not in VMs.. – yakya Jun 10 '18 at 18:47
0

EDIT:

First way, MVVM style

  1. Add event RequestClose to your VM. And raise this event when OkCommand executed.
  2. Where you show your dialog and bind VM to window, also add handler to that event like:

    var window = new MyDialogWindow();

    window.DataContext = loginViewModel;

    loginViewModel.RequestClose += (s, e) =>window.Close();

Second way, pass window as CommandParameter:

Set Name property for your window:

<Button Content = "Ok" Command="{Binding OkCommand}" 
CommandParameter="{Binding ElementName=_windowName}"/>

Or

<Button Content = "Ok" Command="{Binding OkCommand}" 
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>

And close window in command execute:

public void Execute(object parameter)
{
    var wnd = parameter as Window;
    if (wnd!= null)
        wnd.Close();
}

See also: Property IsDefault and IsCancel for Button.

SeeSharp
  • 1,730
  • 11
  • 31