bas
bas

Reputation: 14982

WPF AttachedProperty to close window and act on it in ViewModel

I am trying to redirect the Window Closed event to my ViewModel, but lack the proper hands on experience with AttachedProperties.

The class that holds the AttachedProperty

public class WindowClosedBehavior
{
    public static readonly DependencyProperty ClosedProperty = DependencyProperty.RegisterAttached(
        "Closed",
        typeof (ICommand),
        typeof (WindowClosedBehavior),
        new UIPropertyMetadata(ClosedChanged));

    private static void ClosedChanged(
        DependencyObject target,
        DependencyPropertyChangedEventArgs e)
    {
        var window = target as Window;

        if (window != null)
        {
            // ??
        }
    }

    public static void SetClosed(Window target, ICommand value)
    {
        target.SetValue(ClosedProperty, value);
    }
}

How can I implement the behavior so that it will close the window and trigger the RelayCommand?


The (stripped) ViewModel :

    public RelayCommand WindowClosedCommand { get; private set; }

    public MainCommandsViewModel()
    {
        WindowClosedCommand = new RelayCommand(WindowClosedCommandOnExecuted, WindowClosedCommandOnCanExecute);
    }

MainWindow.xaml

<Window x:Class="TvShowManager.UserInterface.Views.MainWindow"

        <!-- left out irrelevant parts -->
        xmlns:closeBehaviors="clr-namespace:TvShowManager.UserInterface.CloseBehaviors"
        closeBehaviors:WindowClosedBehavior.Closed="{Binding WindowCloseCommand}" >

I simply bind a RelayCommand (WindowCloseCommand) to the attached property.


I tried debugging through this to get better understanding and hopefully figure out how to proceed, but no breakpoints are being hit in the class that holds my attached property. If anybody can explain why my code in WindowClosedBehavior never gets executed I would also greatly appreciate the advice there.

I hope it's clear what I am trying to achieve and that somebody can help me out.

Many thanks

Upvotes: 0

Views: 595

Answers (1)

andreask
andreask

Reputation: 4298

Within the ClosedChanged callback, just store the command and register an event handler to the window's Closed event to invoke the command:

private static ICommand _command;

private static void ClosedChanged(
    DependencyObject target,
    DependencyPropertyChangedEventArgs e)
    {
        var window = target as Window;

        if (window != null)
        {
            _command = e.NewValue as ICommand;
            window.Closed += (sender, args) =>
            {
                if (_command != null)
                    _command.Execute(null);
            }
        }
    }

In addition, you might want to un-register all previously existing event handlers on the window's Closed event, but that is only necessary if you plan to change the WindowClosedBenahior during runtime.

Upvotes: 2

Related Questions