Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello, all

I have a question. How can I implement converting of the Event in the method based ICommand without using System.Window.Interactivity (Blend 3 SDK). Several ways in the Internet have led to the solution when need this library.

E.g. I have a method based on ICommand interface which bind to menuitem Exit (Exit from application with saving results etc.). And I want same method (based on ICommand) bind to close/closing window events but I need cast command to event.

Thanks for solutions
Posted
Updated 1-Feb-13 5:44am
v2

The MVVM Light toolkit has an EventToCommand class that will do the trick. It even supports passing the parameters for the event to the command method. I've used it many times and it works great. If you manually include the toolkit (rather than using NuGet) you can just bring in that functionality and not the other stuff like the ViewModelLocator.

Note, however, that the MVVM Light toolkit requires you to include the fact you are using it if you release your application publicly. Refer to the license info on the web site for more details.
 
Share this answer
 
I found solution but it works with general events based on class Delegate. It method doesn't work with MulticastDelegate's based methods (e.g. closed, closing window events). Remaining to use routed events or lib System.Windows.Interactivity or MVVM light toolkit (thanks for it solution Jason Gleim[^]).

If interestingly below articles where I took info about commands and events:
1) Commands in MVVM[^]
2) Wire any WPF Event to Command on ViewModel[^]
 
Share this answer
 
OK, I implement my closed/closing behaviour

Implementation of the closing event
C#
public partial class Commands
    {
        #region Closing (Window event)
        // Event to command
        private static void Window_Closing(object sender, CancelEventArgs e)
        {
            FrameworkElement element = sender as FrameworkElement;
            if (element == null) return;
            ICommand command = GetClosingCommand(element);
            if(command != null && command.CanExecute(e))
                command.Execute(e);
        }

        // Property
        public static readonly DependencyProperty ClosingCommandProperty =
            DependencyProperty.RegisterAttached("ClosingCommand", typeof(ICommand),
            typeof(Commands), new PropertyMetadata(default(ICommand), OnClosingCommandChanged));

        public static ICommand GetClosingCommand(DependencyObject d) { return (ICommand)d.GetValue(ClosingCommandProperty); }
        public static void SetClosingCommand(DependencyObject d, ICommand value) { d.SetValue(ClosingCommandProperty, value); }

        // Event (add or remove)
        private static void OnClosingCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as Window;
            if (element != null)
            {
                if (e.OldValue == null && e.NewValue != null)
                    element.Closing += Window_Closing;
                else if (e.OldValue != null && e.NewValue == null)
                    element.Closing -= Window_Closing;
            }
        }
        #endregion
    }


Here's we are reating a dependency property and its get and set methods. Then we emplement a ChangeProperty handle where we add or remove our EventHandle to a framework element (in our case it's window class). Event handler just execute a command with CancelEventArgs param.

E.g. of the command
C#
public ICommand ClosingWindowCommand
        {
            get
            {
                return new RelayCommand<canceleventargs>((e)=>
                {
                    MessageBoxResult result = MessageBox.Show(
                        "Are you sure that want to exit from application?",
                        "Exit from application",
                        MessageBoxButton.YesNo, MessageBoxImage.Question);

                    if (result == MessageBoxResult.No) e.Cancel = true;
                });
            }
        }
</canceleventargs>

Just shows message box with two buttons (Yes, No). If user pressed button No then assign to property Cancel of the CancelEventArgs param value true.

XAML (changing our property and binding command)
XML
<window x:class="MyApplication.View.MainWindow" xmlns:x="#unknown">
        x:Name="MainWindowInstance"
...
        xmlns:cmd="clr-namespace:MyApplication.Command"
        DataContext="{Binding CloseTab,ElementName=MainWindowInstance}"
        Title="MainWindow" Height="350" Width="525"
        cmd:Commands.ClosingCommand="{Binding ClosingWindowCommand}">
<!-- TODO MainWindow -->
</window>
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900