5

How I can bind one of my buttons on control to X Button that closes the window ? I just want to create cancel button that just closes the window. I am using MVVM in my code. If possible to do it only in xaml, I just dont have any special code with the button click.

Night Walker
  • 20,638
  • 52
  • 151
  • 228

3 Answers3

7

You can just call the Close() method, which will close the window.

private void MyButton_Click(object s, RoutedEventArgs e)
{
    Close();
}
qJake
  • 16,821
  • 17
  • 83
  • 135
  • 12
    **Don't be afraid to put code in the codebehind of an MVVM application.** If the logic you are implementing is exclusive to the view (in this case, yes, because you're closing the window), then it belongs in the codebehind, not the viewmodel. – qJake May 15 '13 at 20:23
3

If it's WPF (and provided I remember right) you can just use CallMethodAction from the parent as a behavior and utilize Close() method via just XAML. Something like;

Parent Window x:Name="window"

namespaces;

 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

-

<Button Content="Cancel">
    <i:Interaction.Triggers>
      <i:EventTrigger EventName="Click">
        <ei:CallMethodAction
            TargetObject="{Binding ElementName=window}"
            MethodName="Close"/>
      </i:EventTrigger>
    </i:Interaction.Triggers>
  </Button>

Hope this helps.

Chris W.
  • 22,835
  • 3
  • 60
  • 94
  • 3
    Don't forget you need to reference the appropriate blend libraries in your project to use this – Bob Vale May 15 '13 at 20:21
  • Well damn I go and answer it going by the OP specs of xaml only and can't even get an upvote haha wasted effort. – Chris W. May 15 '13 at 21:17
  • 1
    +1 but I wouldn't name my Window... I would use this binding instead. `TargetObject="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"` – Kapitán Mlíko May 15 '13 at 21:20
  • Another good point, and I was just whining but thanks fella's :P – Chris W. May 15 '13 at 21:24
3

MVVM solution without code-behind could also look like this:

View:

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

ViewModel:

public ICommand CloseWindowCommand
{
    get
    {
        return new RelayCommand<Window>(SystemCommands.CloseWindow);
    }
}

But SystemCommands is from so if you rock in some older version of you can also use following.

public ICommand CloseWindowCommand
{
    get
    {
        return new RelayCommand<Window>((window) => window.Close());
    }
}
Kapitán Mlíko
  • 4,498
  • 3
  • 43
  • 60
  • This *technically* breaks the MVVM pattern since the ViewModel is not supposed to have any references to view assemblies (such as System.Windows.*). – qJake May 23 '13 at 13:34
  • @SpikeX I don't want to argue and I know that in this case it's not the best solution and it's not even necessary to do it in VM, but I wouldn't say that MVVM is this strict. You don't use System.Windows.Threading in your VMs? Or Application.Dispatcher? – Kapitán Mlíko May 23 '13 at 14:29
  • Nope. Binding is thread-safe and can happen on a thread that isn't the UI thread, so there's no need for the dispatcher. If you ever needed to use the dispatcher, you would send a decoupled message to the view and the view would take care of it. – qJake May 23 '13 at 14:48
  • @SpikeX Not so fast xD ICommand is from System.Windows.Input namespace... you don't use it in your VMs? Yes I know it's different assembly. It's not my point. In my opinion MVVM is not only about what should use where... it's about what it brings you to do it that way. For example I remember two years ago they were laughing at Prism guy for using code-behind. I have never used code-behind as well. never needed it. I would rather use behavior to have it reusable. But still... What advantage of MVVM am I loosing with my code above? – Kapitán Mlíko May 23 '13 at 15:24
  • Where is written I can't use Window class in VM? I hope it's not in stone somewhere. I can have my VM done and don't need to care how View will look like. Plus I can easily do semething else before closing window. There is no reason I can think of why I can't use Window object in VM. – Kapitán Mlíko May 23 '13 at 15:24
  • No, it's not in stone, obviously you can if you want to, but like I said, *technically speaking*, it breaks the pattern. If you want to follow MVVM perfectly, this will break the pattern. That was my only point. – qJake May 23 '13 at 16:54