Я написал поведение для такого сценария:
using System.Reflection;
using System.Windows;
using System.Windows.Interactivity;
namespace Behaviors
{
public class RedirectRoutedEventBehavior : Behavior<UIElement>
{
public static readonly DependencyProperty RedirectTargetProperty =
DependencyProperty.Register("RedirectTarget", typeof(UIElement),
typeof(RedirectRoutedEventBehavior),
new PropertyMetadata(null));
public static readonly DependencyProperty RoutedEventProperty =
DependencyProperty.Register("RoutedEvent", typeof(RoutedEvent), typeof(RedirectRoutedEventBehavior),
new PropertyMetadata(null, OnRoutedEventChanged));
public UIElement RedirectTarget
{
get => (UIElement) this.GetValue(RedirectTargetProperty);
set => this.SetValue(RedirectTargetProperty, value);
}
public RoutedEvent RoutedEvent
{
get => (RoutedEvent) this.GetValue(RoutedEventProperty);
set => this.SetValue(RoutedEventProperty, value);
}
private static MethodInfo MemberwiseCloneMethod { get; }
= typeof(object)
.GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance);
private static void OnRoutedEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((RedirectRoutedEventBehavior) d).OnRoutedEventChanged((RoutedEvent) e.OldValue, (RoutedEvent) e.NewValue);
}
private void OnRoutedEventChanged(RoutedEvent oldValue, RoutedEvent newValue)
{
if (this.AssociatedObject == null)
{
return;
}
if (oldValue != null)
{
this.AssociatedObject.RemoveHandler(oldValue, new RoutedEventHandler(this.EventHandler));
}
if (newValue != null)
{
this.AssociatedObject.AddHandler(newValue, new RoutedEventHandler(this.EventHandler));
}
}
protected override void OnAttached()
{
base.OnAttached();
if (this.RoutedEvent != null)
{
this.AssociatedObject.AddHandler(this.RoutedEvent, new RoutedEventHandler(this.EventHandler));
}
}
protected override void OnDetaching()
{
if (this.RoutedEvent != null)
{
this.AssociatedObject.RemoveHandler(this.RoutedEvent, new RoutedEventHandler(this.EventHandler));
}
base.OnDetaching();
}
private static RoutedEventArgs CloneEvent(RoutedEventArgs e)
{
return (RoutedEventArgs) MemberwiseCloneMethod.Invoke(e, null);
}
private void EventHandler(object sender, RoutedEventArgs e)
{
var newEvent = CloneEvent(e);
e.Handled = true;
if (this.RedirectTarget != null)
{
newEvent.Source = this.RedirectTarget;
this.RedirectTarget.RaiseEvent(newEvent);
}
}
}
}
Использование:
<ContentControl x:Name="A" Content="Click Me" BorderBrush="Blue">
<i:Interaction.Behaviors>
<behaviors:RedirectRoutedEventBehavior RoutedEvent="UIElement.MouseDown"
RedirectTarget="{Binding ElementName=B}" />
<behaviors:RedirectRoutedEventBehavior RoutedEvent="UIElement.PreviewMouseDown"
RedirectTarget="{Binding ElementName=B}" />
</i:Interaction.Behaviors>
</ContentControl>
<ContentControl x:Name="B" Content="Click Me2" BorderBrush="Blue" />
Это перенаправляет MouseDown
и PreviewMouseDown
события с A
на B
.
Вам нужно Install-Package System.Windows.Interactivity.WPF
для вашего проекта и декларации xmlns:
xmlns:behaviors="clr-namespace:Behaviors"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"