I have the following Behavior:
public class NavigateAndBroadcastAction : NavigateToPageAction
{
protected override void Invoke(object parameter)
{
base.Invoke(parameter);
Messenger.Default.Send<NavigatingMessage<ViewModelBase>>(new NavigatingMessage<ViewModelBase>(this, PassedObject), NavigationToken);
}
public ViewModelBase PassedObject
{
get { return (ViewModelBase)GetValue(PassedObjectProperty); }
set { SetValue(PassedObjectProperty, value); }
}
// Using a DependencyProperty as the backing store for PassedObject. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PassedObjectProperty = DependencyProperty.Register("PassedObject", typeof(ViewModelBase), typeof(NavigateAndBroadcastAction), new PropertyMetadata(null));
...
}
It basically uses the NavigateToPageAction (available in Blend also) but allows me to also broadcast a ViewModel object (I use it to navigate from List page to Detail page and to pass the selected object)
Xaml would look like this: (the PassedObject Binding is to an instance of DetailViewModel which inherits from ViewModelBase)
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<b:NavigateAndBroadcastAction TargetPage="/View/SubjectDetailPage.xaml" NavigationToken="SubjectDetailNavigationToken" PassedObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Now, I want to register for the Message:
Messenger.Default.Register<NavigatingMessage<DetailViewModel>>(this, NavigationToken, true, Action);
But that doesnt work. What does work, is to register for NavigatingMessage<ViewModelBase> and then cast the received message to NavigatingMessage<DetailViewModel>. Is there a way around that?
Can it be done so that the messenger detects the actual type of object being sent and correctly delivers to objects that registed for that type?
One possible way would be to use reflection to send the message, by creating the message with the correct generic type at runtime.
Another one would be to use
dynamicand type inference:The version using reflection is a bit more messy:
This code assumes that
NavigationTokenis astring. If not, just change the type of the second parameter of theSendmethod. IfMessengeronly contains one overload of theSendmethod you could simplify the condition inSingle. On the other hand, if there are a lot of overloads of that method, you might need to refine it.