Dowemo
0 0 0 0


Question:

I have a Button that closes my window when it's clicked:

<Button x:Name="buttonOk"  IsCancel="True">Ok</Button>

That's fine until I add a Command to the Button i.e.

<Button x:Name="buttonOk" 
        Command="{Binding SaveCommand}" 
        IsCancel="True">Ok</Button>

Now it doesn't close presumably because I am handling the Command. I can fix this by putting an EventHandler in and calling this.Close() i.e.

<Button x:Name="buttonOk" 
        Click="closeWindow" 
        Command="{Binding SaveCommand}" 
        IsCancel="True">Ok</Button>

but now I have code in my code behind i.e. the method SaveCommand. I am using the MVVM pattern and SaveCommand is the only code in my code behind.

How can I do this differently so as not to use code behind?


Best Answer:


As someone commented, the code I have posted is not MVVM friendly, how about the second solution?

1st, not MVVM solution (I will not delete this as a reference)

XAML:

<Button Name="okButton" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">OK</Button>

ViewModel:

public ICommand OkCommand
{
    get
    {
        if (_okCommand == null)
        {
            _okCommand = new ActionCommand<Window>(DoOk, CanDoOk);
        }
        return _okCommand ;
    }
}
void DoOk(Window win)
{
    <!--Your Code-->
    win.DialogResult = true;
    win.Close();
}
bool CanDoOk(Window win) { return true; }

2nd, probably better solution:Using attached behaviours

XAML

<Button Content="Ok and Close" Command="{Binding OkCommand}" b:CloseOnClickBehaviour.IsEnabled="True" />

View Model

public ICommand OkCommand
{
    get { return _okCommand; }
}

Behaviour Class Something similar to this:

public static class CloseOnClickBehaviour
{
    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.RegisterAttached(
            "IsEnabled",
            typeof(bool),
            typeof(CloseOnClickBehaviour),
            new PropertyMetadata(false, OnIsEnabledPropertyChanged)
        );
    public static bool GetIsEnabled(DependencyObject obj)
    {
        var val = obj.GetValue(IsEnabledProperty);
        return (bool)val;
    }
    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }
    static void OnIsEnabledPropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs args)
    {
        var button = dpo as Button;
        if (button == null)
            return;
        var oldValue = (bool)args.OldValue;
        var newValue = (bool)args.NewValue;
        if (!oldValue && newValue)
        {
            button.Click += OnClick;
        }
        else if (oldValue && !newValue)
        {
            button.PreviewMouseLeftButtonDown -= OnClick;
        }
    }
    static void OnClick(object sender, RoutedEventArgs e)
    {
        var button = sender as Button;
        if (button == null)
            return;
        var win = Window.GetWindow(button);
        if (win == null)
            return;
        win.Close();
    }
}



Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs