Working on a new WPF/MVVM app I "discovered" routed events and thought that might be of good use for communication between different classes. In my sample some custom data is in a ViewModel named MainWindowViewModel, and when closing the application that data should be saved. Managed to define a new custom RoutedEvent in MainWindow.xaml.cs and a way to Raise it when the user closes the application.
Cannot find the correct way to register for this event in MainWindowViewModel, however. EventManager.GetRoutedEvents() shows me (in debug mode) that my custom event is there!
Is there a way to do this in code or am I walking the wrong path here?
<Window x:Class="RoutedEventA.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vws="clr-namespace:RoutedEventA.Views"
xmlns:vms="clr-namespace:RoutedEventA.ViewModels"
mc:Ignorable="d"
Closing="Window_Closing"
Title="MainWindow" Height="200" Width="400">
<Window.DataContext>
<vms:MainWindowViewModel />
</Window.DataContext>
<Grid>
<vws:MainWindowView/>
</Grid>
namespace RoutedEventA;
public partial class MainWindow : Window
{
public RoutedEvent CloseTheShop = EventManager.RegisterRoutedEvent(
"CloseTheShop", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MainWindow));
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Debug.WriteLine("MainWindow Window_Closing");
RoutedEventArgs close_event = new RoutedEventArgs(CloseTheShop);
this.RaiseEvent(close_event);
}
}
<UserControl x:Class="RoutedEventA.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="400">
<Label Content="MainWindowView" />
</UserControl>
namespace RoutedEventA.Views;
public partial class MainWindowView : UserControl
{
public MainWindowView()
{
Debug.WriteLine("MainWindowView ctor");
InitializeComponent();
}
}
namespace RoutedEventA.ViewModels;
internal class MainWindowViewModel
{
public MainWindowViewModel()
{
Debug.WriteLine("MainWindowViewModel ctor");
var gre = EventManager.GetRoutedEvents();
//
// My Registered Event is in there!
// Now to find out how to regsiter for my custom event and call the Save method.
//
}
//
// The Save method is for all kinds of data of this ViewModel (to be desigend).
//
public void Save()
{
Debug.WriteLine("MainWindow Save");
}
}
The short answer is simple: you can't do that.
The long answer is quite articulated: as I said before, you can't register events directly from view to viewmodel, but you could use a workaround with a nuget package. First of all, reference Microsoft.Xaml.Behaviors.Wpf package in your project: https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Wpf
Then, reference it in your window
So, create an appropriate ICommand in your viewmodel to handle the event raising and bind your event to it (for reasons of length I will not explain how to do it, but you will find all the information you need in this link: ICommand MVVM implementation)